nx_u2048.nx source
↩ module page · 197 lines · 5269 B
1// nx_u2048.nx -- 2048-bit unsigned big-int (64 × 32-bit limbs).
2//
3// Mirrors nx_u256/nx_u384 with limb count 64. Needed for RSA-2048
4// signature verification (Task #68, Web PKI legacy RSA roots like
5// Comodo AAA Certificate Services).
6//
7// Layout: 64 i64 slots, low 32 bits used per limb. Limb 0 LSB.
8// Byte serialization: 256-byte BE (DER) layout.
9//
10// Function names use the `u2048_` prefix to avoid the silent-
11// shadowing bug class fixed 2026-05-20 in nx_sha256/nx_sha512.
12//
13// license_tier: INDEPENDENT_REDERIVE
14// genealogy_id: international-research-sources/ietf/rfc_8017 + nist/fips_186_5
15// lineage_id: nishi_u2048_q10
16
17// nx_safety_envelope:
18// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
19// sil_target: SIL1
20// evidence: [bulk_applied_2026-05-20, u2048-bigint-foundation]
21// verdict: NOT_YET_EVALUATED
22
23import "nx_syscalls.nx"
24
25const NX_U2048_LIMBS: i64 = 64
26const NX_U2048_BYTES: i64 = 256
27const NX_U2048_LIMB_BITS: i64 = 32
28const NX_U2048_LIMB_MASK: i64 = 0xFFFFFFFF
29
30func u2048_alloc() -> *i64 {
31 let b: *u8 = sys_mmap(NX_U2048_LIMBS * 8)
32 let p: *i64 = b as *i64
33 var i: i64 = 0
34 while i < NX_U2048_LIMBS {
35 p[i] = 0
36 i = i + 1
37 }
38 return p
39}
40
41func u2048_zero(out: *i64) -> i64 {
42 var i: i64 = 0
43 while i < NX_U2048_LIMBS {
44 out[i] = 0
45 i = i + 1
46 }
47 return 0
48}
49
50func u2048_one(out: *i64) -> i64 {
51 u2048_zero(out)
52 out[0] = 1
53 return 0
54}
55
56func u2048_copy(out: *i64, src: *i64) -> i64 {
57 var i: i64 = 0
58 while i < NX_U2048_LIMBS {
59 out[i] = src[i]
60 i = i + 1
61 }
62 return 0
63}
64
65// Load 256 BE bytes into LE 64-limb layout.
66func u2048_load_be(out: *i64, bytes: *u8) -> i64 {
67 var i: i64 = 0
68 while i < NX_U2048_LIMBS {
69 let off: i64 = i * 4
70 let limb_idx: i64 = NX_U2048_LIMBS - 1 - i
71 let b0: i64 = bytes[off] & 0xff
72 let b1: i64 = bytes[off + 1] & 0xff
73 let b2: i64 = bytes[off + 2] & 0xff
74 let b3: i64 = bytes[off + 3] & 0xff
75 out[limb_idx] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3
76 i = i + 1
77 }
78 return 0
79}
80
81func u2048_store_be(bytes: *u8, src: *i64) -> i64 {
82 var i: i64 = 0
83 while i < NX_U2048_LIMBS {
84 let off: i64 = i * 4
85 let limb_idx: i64 = NX_U2048_LIMBS - 1 - i
86 let limb: i64 = src[limb_idx]
87 bytes[off] = ((limb >> 24) & 0xff) as u8
88 bytes[off + 1] = ((limb >> 16) & 0xff) as u8
89 bytes[off + 2] = ((limb >> 8) & 0xff) as u8
90 bytes[off + 3] = (limb & 0xff) as u8
91 i = i + 1
92 }
93 return 0
94}
95
96func u2048_add_with_carry(out: *i64, a: *i64, b: *i64) -> i64 {
97 var i: i64 = 0
98 var carry: i64 = 0
99 while i < NX_U2048_LIMBS {
100 let s: i64 = (a[i] & NX_U2048_LIMB_MASK) + (b[i] & NX_U2048_LIMB_MASK) + carry
101 out[i] = s & NX_U2048_LIMB_MASK
102 carry = (s >> NX_U2048_LIMB_BITS) & 1
103 i = i + 1
104 }
105 return carry
106}
107
108func u2048_sub_with_borrow(out: *i64, a: *i64, b: *i64) -> i64 {
109 var i: i64 = 0
110 var borrow: i64 = 0
111 while i < NX_U2048_LIMBS {
112 let d: i64 = (a[i] & NX_U2048_LIMB_MASK) - (b[i] & NX_U2048_LIMB_MASK) - borrow
113 if d < 0 {
114 out[i] = (d + (1 << NX_U2048_LIMB_BITS)) & NX_U2048_LIMB_MASK
115 borrow = 1
116 } else {
117 out[i] = d & NX_U2048_LIMB_MASK
118 borrow = 0
119 }
120 i = i + 1
121 }
122 return borrow
123}
124
125func u2048_cmp(a: *i64, b: *i64) -> i64 {
126 var i: i64 = NX_U2048_LIMBS - 1
127 while i >= 0 {
128 let av: i64 = a[i] & NX_U2048_LIMB_MASK
129 let bv: i64 = b[i] & NX_U2048_LIMB_MASK
130 if av < bv { return 0 - 1 }
131 if av > bv { return 1 }
132 i = i - 1
133 }
134 return 0
135}
136
137func u2048_is_zero(a: *i64) -> i64 {
138 var i: i64 = 0
139 var acc: i64 = 0
140 while i < NX_U2048_LIMBS {
141 acc = acc | (a[i] & NX_U2048_LIMB_MASK)
142 i = i + 1
143 }
144 if acc == 0 { return 1 }
145 return 0
146}
147
148func u2048_eq(a: *i64, b: *i64) -> i64 {
149 var i: i64 = 0
150 var diff: i64 = 0
151 while i < NX_U2048_LIMBS {
152 diff = diff | ((a[i] ^ b[i]) & NX_U2048_LIMB_MASK)
153 i = i + 1
154 }
155 if diff == 0 { return 1 }
156 return 0
157}
158
159// Left-shift by one bit (in place; carries propagate up).
160// Returns carry-out (the bit that fell off the top).
161func u2048_shl1(out: *i64) -> i64 {
162 var i: i64 = 0
163 var carry: i64 = 0
164 while i < NX_U2048_LIMBS {
165 let v: i64 = out[i] & NX_U2048_LIMB_MASK
166 let new_carry: i64 = (v >> 31) & 1
167 out[i] = ((v << 1) | carry) & NX_U2048_LIMB_MASK
168 carry = new_carry
169 i = i + 1
170 }
171 return carry
172}
173
174// Right-shift by one bit (in place).
175func u2048_shr1(out: *i64) -> i64 {
176 var i: i64 = NX_U2048_LIMBS - 1
177 var carry: i64 = 0
178 while i >= 0 {
179 let v: i64 = out[i] & NX_U2048_LIMB_MASK
180 let new_carry: i64 = v & 1
181 out[i] = ((v >> 1) | (carry << 31)) & NX_U2048_LIMB_MASK
182 carry = new_carry
183 i = i - 1
184 }
185 return 0
186}
187
188// Get bit i (0..2047) where bit 0 is LSB.
189func u2048_get_bit(a: *i64, bit: i64) -> i64 {
190 let limb: i64 = bit / 32
191 let pos: i64 = bit % 32
192 return (a[limb] >> pos) & 1
193}
194
195func main() -> i64 {
196 return 0
197}