aboutsummaryrefslogtreecommitdiff
path: root/rust/guts/src/riscv_rva23u64.rs
blob: 7f2a7abb8216defa4acf55d086c06bef8957899b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! This implementation currently assumes riscv_rva23u64_zbb_zvbb. Zvbb in particular ("Vector
//! Bit-manipulation used in Cryptography") is a bleeding-edge extension that was only frozen a few
//! weeks ago at the time I'm writing this comment. Compiling and testing this code currently
//! requires quite a lot of effort, including building Clang from master and building QEMU from a
//! custom branch. Please don't expect this code to be usable on real hardware for some time.

use crate::{BlockBytes, CVBytes, Implementation};

// NOTE: Keep this in sync with the same constant in assembly.
pub(crate) const MAX_SIMD_DEGREE: usize = 16;

extern "C" {
    fn blake3_guts_riscv_rva23u64_degree() -> usize;
    fn blake3_guts_riscv_rva23u64_compress(
        block: *const BlockBytes,
        block_len: u32,
        cv: *const CVBytes,
        counter: u64,
        flags: u32,
        out: *mut CVBytes,
    );
    fn blake3_guts_riscv_rva23u64_hash_chunks(
        input: *const u8,
        input_len: usize,
        key: *const CVBytes,
        counter: u64,
        flags: u32,
        transposed_output: *mut u32,
    );
    fn blake3_guts_riscv_rva23u64_hash_parents(
        transposed_input: *const u32,
        num_parents: usize,
        key: *const CVBytes,
        flags: u32,
        transposed_output: *mut u32,
    );
    fn blake3_guts_riscv_rva23u64_xof(
        block: *const BlockBytes,
        block_len: u32,
        cv: *const CVBytes,
        counter: u64,
        flags: u32,
        out: *mut u8,
        out_len: usize,
    );
    fn blake3_guts_riscv_rva23u64_xof_xor(
        block: *const BlockBytes,
        block_len: u32,
        cv: *const CVBytes,
        counter: u64,
        flags: u32,
        out: *mut u8,
        out_len: usize,
    );
    fn blake3_guts_riscv_rva23u64_universal_hash(
        input: *const u8,
        input_len: usize,
        key: *const CVBytes,
        counter: u64,
        out: *mut [u8; 16],
    );
}

pub fn implementation() -> Implementation {
    Implementation::new(
        blake3_guts_riscv_rva23u64_degree,
        blake3_guts_riscv_rva23u64_compress,
        blake3_guts_riscv_rva23u64_hash_chunks,
        blake3_guts_riscv_rva23u64_hash_parents,
        blake3_guts_riscv_rva23u64_xof,
        blake3_guts_riscv_rva23u64_xof_xor,
        blake3_guts_riscv_rva23u64_universal_hash,
    )
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_compress_vs_portable() {
        crate::test::test_compress_vs_portable(&implementation());
    }

    #[test]
    fn test_compress_vs_reference() {
        crate::test::test_compress_vs_reference(&implementation());
    }

    #[test]
    fn test_hash_chunks_vs_portable() {
        crate::test::test_hash_chunks_vs_portable(&implementation());
    }

    #[test]
    fn test_hash_parents_vs_portable() {
        crate::test::test_hash_parents_vs_portable(&implementation());
    }

    #[test]
    fn test_chunks_and_parents_vs_reference() {
        crate::test::test_chunks_and_parents_vs_reference(&implementation());
    }

    #[test]
    fn test_xof_vs_portable() {
        crate::test::test_xof_vs_portable(&implementation());
    }

    #[test]
    fn test_xof_vs_reference() {
        crate::test::test_xof_vs_reference(&implementation());
    }

    #[test]
    fn test_universal_hash_vs_portable() {
        crate::test::test_universal_hash_vs_portable(&implementation());
    }

    #[test]
    fn test_universal_hash_vs_reference() {
        crate::test::test_universal_hash_vs_reference(&implementation());
    }
}