Skip to content

Commit 56f20d1

Browse files
authored
x.crypto.ascon: small cleanups and optimization (#25284)
1 parent 04e79e7 commit 56f20d1

3 files changed

Lines changed: 48 additions & 20 deletions

File tree

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ fn ascon_pnr(mut s State, nr int) {
4141
if nr < 1 || nr > 16 {
4242
panic('Invalid round number')
4343
}
44+
// Allocate temporary vars to reduce allocation within loop
45+
mut x0 := u64(0)
46+
mut y0 := u64(0)
4447
// Ascon permutation routine
4548
for i := max_nr_perm - nr; i < max_nr_perm; i++ {
4649
// 3.2 Constant-Addition Layer step
@@ -56,18 +59,22 @@ fn ascon_pnr(mut s State, nr int) {
5659
s.e0 ^= s.e4
5760
s.e4 ^= s.e3
5861
s.e2 ^= s.e1
59-
62+
// Set temp vars to values
63+
x0 = s.e0
64+
y0 = s.e4 ^ (~s.e0 & s.e1)
65+
/*
6066
t0 := s.e4 ^ (~s.e0 & s.e1)
6167
t1 := s.e0 ^ (~s.e1 & s.e2)
6268
t2 := s.e1 ^ (~s.e2 & s.e3)
6369
t3 := s.e2 ^ (~s.e3 & s.e4)
6470
t4 := s.e3 ^ (~s.e4 & s.e0)
71+
*/
6572

66-
s.e0 = t1
67-
s.e1 = t2
68-
s.e2 = t3
69-
s.e3 = t4
70-
s.e4 = t0
73+
s.e0 = s.e0 ^ (~s.e1 & s.e2) // t1
74+
s.e1 = s.e1 ^ (~s.e2 & s.e3) // t2
75+
s.e2 = s.e2 ^ (~s.e3 & s.e4) // t3
76+
s.e3 = s.e3 ^ (~s.e4 & x0) // t4, change s.e0 to x0
77+
s.e4 = y0
7178

7279
s.e1 ^= s.e0
7380
s.e0 ^= s.e4

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,28 +135,39 @@ fn (mut d Digest) squeeze(mut dst []u8) int {
135135
}
136136

137137
@[direct_array_access; inline]
138-
fn ascon_generic_hash(mut s State, msg_ []u8, size int) []u8 {
138+
fn ascon_generic_hash(mut s State, msg []u8, size int) []u8 {
139139
// Assumed state was correctly initialized
140140
// Absorbing the message
141-
mut msg := msg_.clone()
142-
for msg.len >= block_size {
143-
s.e0 ^= binary.little_endian_u64(msg[0..block_size])
144-
unsafe {
145-
msg = msg[block_size..]
141+
mut pos := 0
142+
// Check if msg has non-null length, if yes, absorb it.
143+
// Otherwise, just pad it
144+
if _likely_(msg.len > 0) {
145+
mut msg_len := msg.len
146+
for msg_len >= block_size {
147+
s.e0 ^= binary.little_endian_u64(msg[pos..pos + block_size])
148+
pos += block_size
149+
msg_len -= block_size
150+
ascon_pnr(mut s, ascon_prnd_12)
146151
}
147-
ascon_pnr(mut s, ascon_prnd_12)
152+
// Absorb the last partial message block
153+
last_block := unsafe { msg[pos..] }
154+
s.e0 ^= u64(0x01) << (8 * last_block.len) // pad(last_block.len)
155+
if last_block.len > 0 {
156+
s.e0 ^= load_bytes(last_block, last_block.len)
157+
}
158+
} else {
159+
// Otherwise, just pad it
160+
s.e0 ^= u64(0x01)
148161
}
149-
// Absorb the last partial message block
150-
s.e0 ^= load_bytes(msg, msg.len)
151-
s.e0 ^= pad(msg.len)
162+
// reset pos
163+
pos = 0
152164

153165
// Squeezing phase
154166
//
155167
// The squeezing phase begins after msg is absorbed with an
156168
// permutation 𝐴𝑠𝑐𝑜𝑛-𝑝[12] to the state:
157169
ascon_pnr(mut s, ascon_prnd_12)
158170
mut out := []u8{len: size}
159-
mut pos := 0
160171
mut clen := out.len
161172
for clen >= block_size {
162173
binary.little_endian_put_u64(mut out[pos..pos + 8], s.e0)

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,23 @@ fn set_byte(b u8, i int) u64 {
8383
fn load_bytes(bytes []u8, n int) u64 {
8484
mut x := u64(0)
8585
for i := 0; i < n; i++ {
86-
x |= set_byte(bytes[i], i)
86+
// This is the same way to store bytes in little-endian way
87+
// x |= u64(bytes[0]) << 8*0 // LSB at lowest index
88+
// x |= u64(bytes[1]) << 8*1
89+
// x |= u64(bytes[2]) << 8*2
90+
// x |= u64(bytes[3]) << 8*3
91+
// ...etc
92+
// x |= u64(bytes[7]) << 8*7 // MSB at highest index
93+
x |= u64(bytes[i]) << (8 * i)
8794
}
88-
return u64le(x)
95+
// No need to cast with u64le, its alread le
96+
return x
8997
}
9098

99+
@[direct_array_access]
91100
fn store_bytes(mut out []u8, x u64, n int) {
92101
for i := 0; i < n; i++ {
93-
out[i] = get_byte(x, i)
102+
// use underlying get_byte directly
103+
out[i] = u8(x >> (8 * i))
94104
}
95105
}

0 commit comments

Comments
 (0)