Skip to content

Commit 50d03eb

Browse files
authored
x.crypto.ascon: improve ascon_generic_hash, cleanup (#25288)
1 parent 5d7958d commit 50d03eb

5 files changed

Lines changed: 37 additions & 43 deletions

File tree

‎vlib/x/crypto/ascon/aead128.v‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ pub fn (mut c Aead128) encrypt(msg []u8, nonce []u8, ad []u8) ![]u8 {
181181
c.State.e4 = n1
182182

183183
// Update state by permutation
184-
ascon_pnr(mut c.State, ascon_prnd_12)
184+
ascon_pnr(mut c.State, .ascon_prnd_12)
185185
// XOR-ing with the cipher's key
186186
c.State.e3 ^= c.key[0]
187187
c.State.e4 ^= c.key[1]
@@ -229,7 +229,7 @@ pub fn (mut c Aead128) decrypt(ciphertext []u8, nonce []u8, ad []u8) ![]u8 {
229229
c.State.e4 = n1
230230

231231
// scrambled with permutation routine
232-
ascon_pnr(mut c.State, ascon_prnd_12)
232+
ascon_pnr(mut c.State, .ascon_prnd_12)
233233
// xor-ing with the cipher's key
234234
c.State.e3 ^= c.key[0]
235235
c.State.e4 ^= c.key[1]
@@ -288,7 +288,7 @@ fn aead128_init(mut s State, key []u8, nonce []u8) (u64, u64) {
288288
s.e4 = n1
289289

290290
// updates State using the permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[12], S ← 𝐴𝑠𝑐𝑜𝑛-𝑝[12](S)
291-
ascon_pnr(mut s, ascon_prnd_12)
291+
ascon_pnr(mut s, .ascon_prnd_12)
292292

293293
// Then XORing the secret key 𝐾 into the last 128 bits of internal state:
294294
// S ← S ⊕ (0¹⁹² ∥ 𝐾).
@@ -312,7 +312,7 @@ fn aead128_process_ad(mut s State, ad []u8) {
312312
s.e1 ^= binary.little_endian_u64(block[8..16])
313313

314314
// Apply permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[8] to the state
315-
ascon_pnr(mut s, ascon_prnd_8)
315+
ascon_pnr(mut s, .ascon_prnd_8)
316316
// Updates index
317317
ad_length -= aead128_block_size
318318
ad_idx += aead128_block_size
@@ -339,7 +339,7 @@ fn aead128_process_ad(mut s State, ad []u8) {
339339
}
340340
}
341341
// Apply permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[8] to the state
342-
ascon_pnr(mut s, ascon_prnd_8)
342+
ascon_pnr(mut s, .ascon_prnd_8)
343343
}
344344
// The final step of processing associated data is to update the state
345345
// with a constant that provides domain separation.
@@ -361,7 +361,7 @@ fn aead128_process_msg(mut out []u8, mut s State, msg []u8) int {
361361
binary.little_endian_put_u64(mut out[pos..pos + 8], s.e0)
362362
binary.little_endian_put_u64(mut out[pos + 8..], s.e1)
363363
// apply permutation
364-
ascon_pnr(mut s, ascon_prnd_8)
364+
ascon_pnr(mut s, .ascon_prnd_8)
365365

366366
// updates index
367367
mlen -= aead128_block_size
@@ -413,7 +413,7 @@ fn aead128_partial_dec(mut out []u8, mut s State, cmsg []u8) {
413413
s.e0 = c0
414414
s.e1 = c1
415415

416-
ascon_pnr(mut s, ascon_prnd_8)
416+
ascon_pnr(mut s, .ascon_prnd_8)
417417
// updates index
418418
pos += aead128_block_size
419419
cmsg_len -= aead128_block_size
@@ -448,7 +448,7 @@ fn aead128_finalize(mut s State, k0 u64, k1 u64) {
448448
s.e2 ^= k0
449449
s.e3 ^= k1
450450
// then updated using the permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[12]
451-
ascon_pnr(mut s, ascon_prnd_12)
451+
ascon_pnr(mut s, .ascon_prnd_12)
452452

453453
// Finally, the tag 𝑇 is generated by XORing the key with the last 128 bits of the state:
454454
// 𝑇 ← 𝑆[192∶319] ⊕ 𝐾.

‎vlib/x/crypto/ascon/ascon.v‎

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ module ascon
1111
const max_nr_perm = 16
1212

1313
// The number how many round(s) for the Ascon permutation routine called.
14-
const ascon_prnd_8 = 8
15-
const ascon_prnd_12 = 12
14+
enum PrndEnum {
15+
ascon_prnd_6 = 6
16+
ascon_prnd_8 = 8
17+
ascon_prnd_12 = 12
18+
}
1619

1720
// The constants to derive round constants of the Ascon permutations
1821
// See Table 5. of NIST SP 800-232 docs
@@ -36,16 +39,12 @@ const rnc = [u8(0x3c), 0x2d, 0x1e, 0x0f, 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x9
3639
// 2. the substitution layer (see Sec.3.3), and,
3740
// 3. the linear diffusion layer (Sec 3.4)
3841
@[direct_array_access]
39-
fn ascon_pnr(mut s State, nr int) {
40-
// We dont allow nr == 0
41-
if nr < 1 || nr > 16 {
42-
panic('Invalid round number')
43-
}
42+
fn ascon_pnr(mut s State, nr PrndEnum) {
4443
// Allocate temporary vars to reduce allocation within loop
4544
mut x0 := u64(0)
4645
mut y0 := u64(0)
4746
// Ascon permutation routine
48-
for i := max_nr_perm - nr; i < max_nr_perm; i++ {
47+
for i := max_nr_perm - int(nr); i < max_nr_perm; i++ {
4948
// 3.2 Constant-Addition Layer step
5049
//
5150
// The constant-addition layer adds a 64-bit round constant 𝑐𝑖
@@ -59,16 +58,10 @@ fn ascon_pnr(mut s State, nr int) {
5958
s.e0 ^= s.e4
6059
s.e4 ^= s.e3
6160
s.e2 ^= s.e1
61+
6262
// Set temp vars to values
6363
x0 = s.e0
6464
y0 = s.e4 ^ (~s.e0 & s.e1)
65-
/*
66-
t0 := s.e4 ^ (~s.e0 & s.e1)
67-
t1 := s.e0 ^ (~s.e1 & s.e2)
68-
t2 := s.e1 ^ (~s.e2 & s.e3)
69-
t3 := s.e2 ^ (~s.e3 & s.e4)
70-
t4 := s.e3 ^ (~s.e4 & s.e0)
71-
*/
7265

7366
s.e0 = s.e0 ^ (~s.e1 & s.e2) // t1
7467
s.e1 = s.e1 ^ (~s.e2 & s.e3) // t2
@@ -97,11 +90,11 @@ fn ascon_pnr(mut s State, nr int) {
9790
// Bits right rotation, basically can be defined as:
9891
// ror = (x >> n) | x << (64 - n) for some u64 x
9992
//
100-
s.e0 ^= (s.e0 >> 19 | (s.e0 << (64 - 19))) ^ (s.e0 >> 28 | (s.e0 << (64 - 28)))
101-
s.e1 ^= (s.e1 >> 61 | (s.e1 << (64 - 61))) ^ (s.e1 >> 39 | (s.e1 << (64 - 39)))
102-
s.e2 ^= (s.e2 >> 1 | (s.e2 << (64 - 1))) ^ (s.e2 >> 6 | (s.e2 << (64 - 6))) //
103-
s.e3 ^= (s.e3 >> 10 | (s.e3 << (64 - 10))) ^ (s.e3 >> 17 | (s.e3 << (64 - 17)))
104-
s.e4 ^= (s.e4 >> 7 | (s.e4 << (64 - 7))) ^ (s.e4 >> 41 | (s.e4 << (64 - 41)))
93+
s.e0 ^= (s.e0 >> 19 | s.e0 << 45) ^ (s.e0 >> 28 | s.e0 << 36)
94+
s.e1 ^= (s.e1 >> 61 | s.e1 << 3) ^ (s.e1 >> 39 | s.e1 << 25)
95+
s.e2 ^= (s.e2 >> 1 | s.e2 << 63) ^ (s.e2 >> 6 | s.e2 << 58)
96+
s.e3 ^= (s.e3 >> 10 | s.e3 << 54) ^ (s.e3 >> 17 | s.e3 << 47)
97+
s.e4 ^= (s.e4 >> 7 | s.e4 << 57) ^ (s.e4 >> 41 | s.e4 << 23)
10598
}
10699
}
107100

‎vlib/x/crypto/ascon/ascon_test.v‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn test_ascon_round_p6() {
1313
e3: 0xabcdef0123456789
1414
e4: 0x89abcdef01234567
1515
}
16-
ascon_pnr(mut s, 6)
16+
ascon_pnr(mut s, .ascon_prnd_6)
1717
assert s.e0 == u64(0xc27b505c635eb07f)
1818
assert s.e1 == u64(0xd388f5d2a72046fa)
1919
assert s.e2 == u64(0x9e415c204d7b15e7)
@@ -29,7 +29,7 @@ fn test_ascon_round_p8() {
2929
e3: 0xabcdef0123456789
3030
e4: 0x89abcdef01234567
3131
}
32-
ascon_pnr(mut s, 8)
32+
ascon_pnr(mut s, .ascon_prnd_8)
3333
assert s.e0 == u64(0x67ed228272f46eee)
3434
assert s.e1 == u64(0x80bc0b097aad7944)
3535
assert s.e2 == u64(0x2fa599382c6db215)
@@ -45,7 +45,7 @@ fn test_ascon_round_p12() {
4545
e3: 0xabcdef0123456789
4646
e4: 0x89abcdef01234567
4747
}
48-
ascon_pnr(mut s, 12)
48+
ascon_pnr(mut s, .ascon_prnd_12)
4949
assert s.e0 == u64(0x206416dfc624bb14)
5050
assert s.e1 == u64(0x1b0c47a601058aab)
5151
assert s.e2 == u64(0x8934cfc93814cddd)

‎vlib/x/crypto/ascon/digest.v‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn (mut d Digest) finish() {
3333
d.State.e0 ^= load_bytes(d.buf[..d.length], d.length)
3434

3535
// Permutation step was done in squeezing-phase
36-
// ascon_pnr(mut d.State, ascon_prnd_12)
36+
// ascon_pnr(mut d.State, .ascon_prnd_12)
3737

3838
// zeroing Digest buffer
3939
d.length = 0
@@ -70,7 +70,7 @@ fn (mut d Digest) absorb(msg_ []u8) int {
7070
// If this d.buf length has reached block_size bytes, absorb it.
7171
if d.length == block_size {
7272
d.State.e0 ^= binary.little_endian_u64(d.buf)
73-
ascon_pnr(mut d.State, ascon_prnd_12)
73+
ascon_pnr(mut d.State, .ascon_prnd_12)
7474
// reset the internal buffer
7575
d.length = 0
7676
d.buf.reset()
@@ -87,7 +87,7 @@ fn (mut d Digest) absorb(msg_ []u8) int {
8787
for msg.len >= block_size {
8888
d.State.e0 ^= binary.little_endian_u64(msg[0..block_size])
8989
msg = msg[block_size..]
90-
ascon_pnr(mut d.State, ascon_prnd_12)
90+
ascon_pnr(mut d.State, .ascon_prnd_12)
9191
}
9292
// If there are partial block, just stored into buffer.
9393
if msg.len > 0 {
@@ -113,14 +113,14 @@ fn (mut d Digest) squeeze(mut dst []u8) int {
113113
}
114114
// The squeezing phase begins after msg is absorbed with an
115115
// permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[12] to the state:
116-
ascon_pnr(mut d.State, ascon_prnd_12)
116+
ascon_pnr(mut d.State, .ascon_prnd_12)
117117

118118
mut pos := 0
119119
mut clen := dst.len
120120
// process for full block size
121121
for clen >= block_size {
122122
binary.little_endian_put_u64(mut dst[pos..pos + 8], d.State.e0)
123-
ascon_pnr(mut d.State, ascon_prnd_12)
123+
ascon_pnr(mut d.State, .ascon_prnd_12)
124124
pos += block_size
125125
clen -= block_size
126126
}
@@ -144,10 +144,11 @@ fn ascon_generic_hash(mut s State, msg []u8, size int) []u8 {
144144
if _likely_(msg.len > 0) {
145145
mut msg_len := msg.len
146146
for msg_len >= block_size {
147-
s.e0 ^= binary.little_endian_u64(msg[pos..pos + block_size])
147+
block := unsafe { msg[pos..pos + block_size] }
148+
s.e0 ^= binary.little_endian_u64(block)
148149
pos += block_size
149150
msg_len -= block_size
150-
ascon_pnr(mut s, ascon_prnd_12)
151+
ascon_pnr(mut s, .ascon_prnd_12)
151152
}
152153
// Absorb the last partial message block
153154
last_block := unsafe { msg[pos..] }
@@ -166,12 +167,12 @@ fn ascon_generic_hash(mut s State, msg []u8, size int) []u8 {
166167
//
167168
// The squeezing phase begins after msg is absorbed with an
168169
// permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[12] to the state:
169-
ascon_pnr(mut s, ascon_prnd_12)
170+
ascon_pnr(mut s, .ascon_prnd_12)
170171
mut out := []u8{len: size}
171172
mut clen := out.len
172173
for clen >= block_size {
173174
binary.little_endian_put_u64(mut out[pos..pos + 8], s.e0)
174-
ascon_pnr(mut s, ascon_prnd_12)
175+
ascon_pnr(mut s, .ascon_prnd_12)
175176
pos += block_size
176177
clen -= block_size
177178
}

‎vlib/x/crypto/ascon/xof.v‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,15 +300,15 @@ pub fn (mut x CXof128) free() {
300300
fn cxof128_absorb_custom_string(mut s State, cs []u8) {
301301
// absorb Z0, the length of the customization string (in bits) encoded as a u64
302302
s.e0 ^= u64(cs.len) << 3
303-
ascon_pnr(mut s, ascon_prnd_12)
303+
ascon_pnr(mut s, .ascon_prnd_12)
304304

305305
// absorb the customization string
306306
mut zlen := cs.len
307307
mut zidx := 0
308308
for zlen >= block_size {
309309
block := unsafe { cs[zidx..zidx + block_size] }
310310
s.e0 ^= binary.little_endian_u64(block)
311-
ascon_pnr(mut s, ascon_prnd_12)
311+
ascon_pnr(mut s, .ascon_prnd_12)
312312

313313
// updates a index
314314
zlen -= block_size
@@ -318,5 +318,5 @@ fn cxof128_absorb_custom_string(mut s State, cs []u8) {
318318
last_block := unsafe { cs[zidx..] }
319319
s.e0 ^= load_bytes(last_block, last_block.len)
320320
s.e0 ^= pad(last_block.len)
321-
ascon_pnr(mut s, ascon_prnd_12)
321+
ascon_pnr(mut s, .ascon_prnd_12)
322322
}

0 commit comments

Comments
 (0)