Skip to main content

rhdl_ed25519_scalable_core/ubft/
beats.rs

1//! Packing a 64-byte stream beat into words and back, and picking a free tag.
2
3use super::*;
4
5/// A beat's bytes as eight little-endian words.
6#[kernel]
7pub fn beat_words(data: [b8; 64]) -> [b64; 8] {
8    let mut w = [b64(0); 8];
9    for i in 0..8 {
10        for j in 0..8 {
11            w[i] = w[i] | (data[8 * i + j].resize::<64>() << b64((8 * j) as u128));
12        }
13    }
14    w
15}
16
17/// Eight little-endian words as a beat's bytes.
18#[kernel]
19pub fn words_beat(w: [b64; 8]) -> [b8; 64] {
20    let mut data = [b8(0); 64];
21    for i in 0..8 {
22        for j in 0..8 {
23            data[8 * i + j] = (w[i] >> b64((8 * j) as u128)).resize();
24        }
25    }
26    data
27}
28
29/// The message a sign beat asks for, layout v2 (ABI 2): bytes 8..56 of the
30/// beat (words 1..7), zero-extended to 64 bytes. Bytes 0..8 are the tag and
31/// are not signed. The service signs exactly this; tests call it to get the
32/// same bytes.
33#[kernel]
34pub fn sign_message(words_in: [b64; 8]) -> [b64; 8] {
35    let mut message = [b64(0); 8];
36    for k in 0..6 {
37        message[k] = words_in[k + 1];
38    }
39    message
40}
41
42/// The lowest set bit of a tag table's free mask (index 0 if none is set).
43#[kernel]
44pub fn lowest_free(mask: b16) -> b4 {
45    let mut found = false;
46    let mut idx = b4(0);
47    for k in 0..16 {
48        if !found && ((mask >> b16(k as u128)) & b16(1)) != b16(0) {
49            found = true;
50            idx = b4(k as u128);
51        }
52    }
53    idx
54}