Skip to content

Commit c926e1c

Browse files
authored
x.crypto.chacha20poly1305: small clean up of internal mac generator and encryption routine (#25569)
1 parent c362849 commit c926e1c

1 file changed

Lines changed: 31 additions & 24 deletions

File tree

  • vlib/x/crypto/chacha20poly1305

vlib/x/crypto/chacha20poly1305/psiv.v

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// See the detail on the [A Robust Variant of ChaCha20-Poly1305](https://eprint.iacr.org/2025/222).
1010
module chacha20poly1305
1111

12-
import arrays
1312
import encoding.binary
1413
import crypto.internal.subtle
1514
import x.crypto.chacha20
@@ -157,42 +156,51 @@ pub fn (c Chacha20Poly1305RE) decrypt(ciphertext []u8, nonce []u8, ad []u8) ![]u
157156
// for encrypting (or decrypting) message.
158157
@[direct_array_access]
159158
fn psiv_encrypt_internal(plaintext []u8, key []u8, tag []u8, nonce []u8) ![]u8 {
160-
tctr, trest := split_tag(tag)
161-
mut ctr := binary.little_endian_u64(tctr)
159+
// loads the counter from the first 8-bytes of the tag input
160+
mut ctr := binary.little_endian_u64(tag[0..8])
162161

163-
mut dst := []u8{cap: plaintext.len}
162+
// setup some temporary vars
163+
mut dst := []u8{len: plaintext.len}
164164
mut tc := []u8{len: 8} // counter buffer
165165
mut s := chacha20.State{}
166166
mut b64 := []u8{len: 64} // state buffer
167+
mut tt := merge_drv_key(key, nonce, tag[0..8], tag[8..16])
167168

168-
// split out plaintext messages into 64-bytes chunk, and process them
169-
// chunk by chunk.
170-
chunks := arrays.chunk[u8](plaintext, 64)
171-
for chunk in chunks {
169+
mut j := 0
170+
mut n := 0
171+
172+
// process for every bytes on plaintext input
173+
for plaintext[n..].len > 0 {
174+
// how many block of bytes available to process on
175+
want_len := if plaintext[n..].len < 64 { plaintext[n..].len } else { 64 }
172176
// loads current counter
173177
binary.little_endian_put_u64(mut tc, ctr)
174178

175-
// loads 64-bytes of merged key into state s and then perform chacha20 qround.
176-
// then xor-ing every bytes of result with the bytes in chunk and appended into
177-
// destination output buffer.
178-
unpack_into_state(mut s, merge_drv_key(key, nonce, tc, trest))
179-
buf := chacha20_core(s)
180-
pack64_from_state(mut b64, buf)
181-
for i, v in chunk {
182-
o := v ^ b64[i]
183-
dst << o
179+
// updates derived keys with current counter, scrambled with chacha20_core and
180+
// puts state into b64 buffer
181+
unsafe { vmemcpy(tt[48], tc.data, tc.len) }
182+
unpack_into_state(mut s, tt)
183+
ws := chacha20_core(s)
184+
pack64_from_state(mut b64, ws)
185+
186+
// xor every bytes of plaintext with bytes on b64, stores result in dst
187+
for i in 0 .. want_len {
188+
dst[j] = plaintext[j] ^ b64[i]
189+
j++
184190
}
185191
// updates current counter and returns error on overflow.
186192
ctr += 1
187193
if ctr == 0 {
188194
return error('counter overflowing')
189195
}
196+
n += want_len
190197
}
191-
// reset (release) temporary allocated resources
198+
// reset (release) temporary allocated resources and return the result.
192199
unsafe {
193200
tc.free()
194201
s.reset()
195202
b64.free()
203+
tt.free()
196204
}
197205
return dst
198206
}
@@ -216,18 +224,17 @@ fn psiv_gen_tag(mut po poly1305.Poly1305, input []u8, ad_len int, mac_key []u8,
216224
unpack_into_state(mut x, drv_key)
217225
ws := chacha20_core(x)
218226

219-
// truncating state output into tag sized bytes
220-
mut tag := []u8{len: tag_size}
221-
pack16_from_state(mut tag, ws)
227+
// truncating state output into tag_sized bytes. As a note, we reuse digest buffer allocated
228+
// on previous step to store the result.
229+
pack16_from_state(mut digest, ws)
222230

223-
// releases (reset) temporary allocated resources
231+
// releases (reset) temporary allocated resources and return the result.
224232
unsafe {
225233
drv_key.free()
226-
digest.free()
227234
ws.reset()
228235
x.reset()
229236
}
230-
return tag
237+
return digest
231238
}
232239

233240
// psiv_init initializes and expands master key into desired psiv needed construct.

0 commit comments

Comments
 (0)