compiler/ lib/ examples/ std/ arch/ rv64/ tests/ abi.sizes.rad 3.4 KiB aggregate.return.rad 4.0 KiB arith.assignment.rad 580 B arith.basic.rad 176 B arith.modulo.rad 96 B arith.subword.rad 3.8 KiB arith.sum.rad 177 B arith.w64.rad 4.1 KiB array.assign.rad 221 B array.bounds.check.rad 321 B array.index.assign.rad 367 B array.index.rad 249 B array.length.rad 262 B array.math.rad 1.2 KiB array.nested.assign.rad 319 B array.nested.rad 325 B array.record.elements.rad 1.7 KiB array.repeat.edge.rad 548 B array.repeat.rad 828 B array.return.rad 330 B array.slice.empty.rad 108 B array.slice.gen.end.rad 126 B array.slice.gen.index.rad 139 B array.slice.gen.open.rad 125 B array.slice.gen.start.end.rad 127 B array.slice.gen.start.rad 126 B array.slice.rad 759 B as.precedence.rad 212 B assert.basic.rad 387 B assert.fail.rad 138 B assert.false.rad 140 B assert.true.rad 100 B assign.mutable.rad 6.1 KiB assign.rad 129 B assign.shadow.mutable.rad 461 B binop.bitwise.rad 1.2 KiB binop.cmp.rad 426 B bool.comparison.array.rad 688 B bool.comparison.nested.gen.rad 1.0 KiB bool.comparison.opt.rad 905 B bool.comparison.record.gen.rad 1.0 KiB bool.comparison.record.rad 1.1 KiB bool.comparison.slice.gen.rad 157 B bool.comparison.slice.rad 4.1 KiB bool.comparison.slice.record.gen.rad 2.0 KiB bool.comparison.slice.union.gen.rad 2.5 KiB bool.comparison.union.ctor.rad 690 B bool.comparison.union.gen.rad 1.2 KiB bool.comparison.union.record.gen.rad 1.5 KiB bool.comparison.union.simple.gen.rad 281 B bool.operators.complex.rad 384 B bool.operators.rad 831 B bool.short.circuit.rad 2.3 KiB bool.simple.rad 194 B bool.values.rad 772 B builtin.size.align.rad 1.3 KiB builtin.sliceof.mut.rad 606 B builtin.sliceof.rad 505 B call.arg.clobber.rad 717 B call.basic.rad 241 B call.clobber.rad 462 B cast.same.size.rad 1.0 KiB casting.numbers.rad 1.5 KiB char.literal.rad 165 B compound.assign.field.rad 285 B compound.assign.rad 1.1 KiB cond.assign.rad 723 B cond.expr.aggregate.rad 1.1 KiB cond.expr.rad 1.8 KiB cond.for.else.break.rad 326 B cond.for.indexed.rad 238 B cond.for.rad 165 B cond.for.range.indexed.rad 526 B cond.for.range.rad 171 B cond.for.unsigned.range.rad 644 B cond.forever.break.continue.rad 182 B cond.forever.break.rad 232 B cond.fused.rad 926 B cond.if.case.rad 2.2 KiB cond.if.else.min.rad 143 B cond.if.else.rad 225 B cond.if.elseif.rad 420 B cond.if.noelse.rad 120 B cond.if.rad 865 B cond.match.fallthrough.rad 369 B cond.match.guard.rad 1.4 KiB cond.match.guard.regalloc.rad 1.3 KiB cond.while.else.break.rad 282 B cond.while.rad 119 B const.array.copy.mutate.rad 386 B const.array.rad 195 B const.basic.rad 325 B const.char.rad 159 B const.fn.array.rad 664 B const.record.array.rad 1.2 KiB const.record.array.simple.rad 523 B const.record.ctor.rad 170 B const.record.fn.rad 353 B const.record.rad 182 B const.slice.param.rad 333 B const.union.payload.ctor.rad 349 B const.union.record.literal.rad 359 B data.array.rad 767 B data.bool.rad 216 B data.i16.rad 261 B data.i32.rad 281 B data.i8.rad 248 B data.record.rad 561 B data.simple.rad 436 B data.u16.rad 220 B data.u32.rad 240 B data.u8.rad 208 B data.union.rad 886 B debug.tag.rad 557 B edge.cases.2.rad 337 B edge.cases.3.rad 594 B edge.cases.4.rad 1.2 KiB edge.cases.5.rad 1.0 KiB edge.cases.6.rad 2.6 KiB edge.cases.7.addr.bug.rad 224 B edge.cases.8.bug.rad 508 B edge.cases.rad 223 B error.basic.rad 159 B error.catch.rad 1.6 KiB error.division.zero.rad 164 B error.modulo.zero.rad 162 B error.multi.basic.rad 672 B error.multi.catch.rad 772 B error.multi.catch.typed.binding.rad 791 B error.multi.catch.typed.catchall.rad 1.0 KiB error.multi.catch.typed.rad 1.1 KiB error.multi.propagate.multi.rad 953 B error.multi.propagate.rad 825 B error.multi.try.optional.rad 507 B error.slice.bounds.rad 219 B error.try.bang.success.rad 370 B error.try.catch.binding.rad 2.0 KiB error.try.optional.rad 1.8 KiB error.try.rad 4.0 KiB fn.block.scope.rad 508 B fn.callback.nested.rad 1.2 KiB fn.default.rad 131 B fn.local.rad 140 B fn.recursion.2.rad 239 B fn.void.rad 150 B for.else.continue.rad 1.1 KiB frame.large.rad 567 B if-let-mut.rad 1.1 KiB iflet.shadow.leak.rad 317 B integer.bitwise.basic.rad 693 B integer.overflow.rad 1.8 KiB large.blit.store.rad 2.1 KiB let.guard.rad 1.9 KiB literal.w64.rad 1.7 KiB loc.addr.offset.bug.rad 410 B loc.addr.opt.to.opt.rad 433 B loc.addr.optional.assign.rad 408 B loc.addr.record.assign.rad 443 B loop.complex.flow.rad 1007 B loop.sealblock.rad 911 B match.array.rad 3.4 KiB match.char.rad 1.6 KiB match.multi.seal.rad 987 B match.multi.survive.rad 1.6 KiB match.mutref.push.rad 1.0 KiB match.mutref.union.rad 662 B match.nested.call.rad 1.7 KiB match.nested.deep.rad 2.2 KiB match.nested.deref.rad 3.7 KiB match.nested.guard.rad 1.6 KiB match.nested.iflet.guard.rad 1.6 KiB match.nested.iflet.rad 1.4 KiB match.nested.letelse.rad 813 B match.nested.letelse.union.rad 1.3 KiB match.nested.literal.rad 3.1 KiB match.nested.multi.rad 2.4 KiB match.nested.pattern.rad 5.2 KiB match.nested.record.rad 2.0 KiB match.nested.union.rad 2.3 KiB match.nested.whilelet.rad 2.4 KiB match.string.rad 1.8 KiB match.value.copy.rad 2.0 KiB match.void.then.or.rad 1.6 KiB memzero.result.bug.rad 806 B memzero.union.bug.rad 576 B mutref.loop.bug.rad 1.8 KiB opt.assignment.bug.rad 1.3 KiB opt.bug.test.rad 1.4 KiB opt.if.let.complex.rad 6.2 KiB opt.if.let.guard.rad 809 B opt.if.let.rad 956 B opt.nil.check.rad 1.5 KiB opt.record.eq.rad 842 B opt.record.rad 655 B opt.return.array.rad 289 B opt.return.nested.rad 797 B opt.return.record.rad 344 B opt.slice.npo.rad 2.8 KiB opt.type.rad 200 B opt.while.let.complex.rad 404 B panic.rad 111 B placeholder.basic.rad 133 B placeholder.comprehensive.rad 562 B pointer.copy.edge.case.rad 1.3 KiB pointer.slice.index.rad 269 B pointer.slice.store.rad 881 B prog.ackermann.rad 5.0 KiB prog.bignum.rad 9.4 KiB prog.binsearch.rad 2.4 KiB prog.bubblesort.rad 2.0 KiB prog.cordic.rad 6.9 KiB prog.crc32.rad 2.7 KiB prog.dijkstra.rad 7.7 KiB prog.eval.rad 6.2 KiB prog.hanoi.rad 3.8 KiB prog.huffman.rad 9.3 KiB prog.hybridsort.rad 3.0 KiB prog.linkedlist.rad 5.8 KiB prog.lzw.rad 6.7 KiB prog.matmul.rad 2.9 KiB prog.mersenne.rad 5.2 KiB prog.nqueens.rad 3.4 KiB prog.rbtree.rad 8.2 KiB prog.regex.rad 10.2 KiB prog.sha256.rad 7.0 KiB prog.sieve.rad 2.8 KiB prog.symtab.rad 10.1 KiB prog.tokenizer.rad 13.8 KiB prog.vm.rad 17.4 KiB ptr.assign.rad 137 B ptr.deref.rad 622 B ptr.eq.rad 966 B ptr.mutate.rad 244 B ptr.opaque.rad 1.4 KiB record.access.rad 285 B record.alignment.rad 179 B record.array.elements.rad 1.7 KiB record.copy.rad 2.0 KiB record.field.assign.rad 184 B record.nested.calls.2.rad 612 B record.nested.calls.3.rad 734 B record.param.lit.rad 353 B record.ptr.access.rad 227 B record.ptr.mutate.rad 243 B record.shorthand.rad 1.5 KiB record.unlabeled.rad 407 B ref.if.bug.rad 519 B ref.immut.loop.bug.rad 670 B ref.mut.ptr.rad 261 B regalloc.callee.save.rad 1.5 KiB regalloc.spill.reuse.rad 473 B reserve.loop.rad 392 B result.void.success.rad 716 B slice.alloc.loop.rad 788 B slice.append.rad 3.3 KiB slice.cap.rad 941 B slice.delete.rad 971 B slice.of.rad 460 B slice.subslice.rad 1.4 KiB spill.blockarg.clobber.rad 3.5 KiB spill.loop.rad 1.6 KiB stack.local.corrupt.rad 320 B static.array.mutate.rad 387 B static.basic.rad 327 B static.fn.array.rad 628 B static.record.array.rad 503 B static.slice.index.assign.rad 408 B static.slice.offset.rad 668 B string.basic.rad 149 B string.escape.rad 349 B string.index.rad 116 B switch.blockargs.clobber.rad 1.3 KiB trait.aggregate.ret.rad 1.5 KiB trait.array.optional.rad 1.7 KiB trait.basic.rad 565 B trait.control.flow.rad 1.1 KiB trait.fn.param.rad 1.6 KiB trait.multiple.methods.rad 1.2 KiB trait.multiple.traits.rad 1.2 KiB trait.multiple.types.rad 1.3 KiB trait.supertrait.rad 2.5 KiB trait.throws.rad 1.0 KiB trait.writer.rad 2.6 KiB type.unify.rad 4.5 KiB undefined.rad 417 B union-tag.rad 911 B union.bitfield.rad 1.2 KiB union.discriminant.cast.rad 389 B union.edge.case.2.rad 679 B union.edge.case.3.rad 608 B union.mixed.assign.rad 977 B union.payload.mutref.rad 1.4 KiB union.payload.rad 580 B union.record.forward.rad 1.3 KiB union.void.match.rad 403 B union.void.rad 824 B unsigned.compare.rad 1.9 KiB var.align.rad 1013 B var.infer.rad 549 B decode.rad 14.6 KiB emit.rad 24.4 KiB encode.rad 19.9 KiB isel.rad 41.1 KiB printer.rad 13.0 KiB tests.rad 15.7 KiB rv64.rad 13.0 KiB collections/ lang/ sys/ arch.rad 65 B collections.rad 36 B fmt.rad 3.8 KiB intrinsics.rad 206 B io.rad 1.2 KiB lang.rad 222 B mem.rad 2.2 KiB sys.rad 167 B testing.rad 2.4 KiB tests.rad 11.6 KiB vec.rad 3.1 KiB std.rad 231 B scripts/ seed/ test/ vim/ .gitignore 353 B .gitsigners 112 B LICENSE 1.1 KiB Makefile 3.1 KiB README 2.5 KiB std.lib 987 B std.lib.test 252 B
lib/std/arch/rv64/tests/prog.sha256.rad 7.0 KiB raw
1
//! SHA-256 (single block).
2
//! Implement the SHA-256 compression function for a single 512-bit block.
3
//! Verify against a known hash of a short message.
4
5
/// SHA-256 mutable state: hash values and message schedule.
6
record Sha256 {
7
    h: [u32; 8],
8
    w: [u32; 64],
9
}
10
11
/// SHA-256 initial hash values (first 32 bits of fractional parts of square
12
/// roots of the first 8 primes).
13
const INIT_H: [u32; 8] = [
14
    0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
15
    0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
16
];
17
18
/// Right-rotate a 32-bit value by `n` bits.
19
fn rotr(x: u32, n: u32) -> u32 {
20
    return (x >> n) | (x << (32 - n));
21
}
22
23
/// SHA-256 Ch function: Ch(e, f, g) = (e AND f) XOR (NOT e AND g).
24
fn ch(e: u32, f: u32, g: u32) -> u32 {
25
    return (e & f) ^ (~e & g);
26
}
27
28
/// SHA-256 Maj function: Maj(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c).
29
fn maj(a: u32, b: u32, c: u32) -> u32 {
30
    return (a & b) ^ (a & c) ^ (b & c);
31
}
32
33
/// SHA-256 big sigma 0: rotr(a, 2) XOR rotr(a, 13) XOR rotr(a, 22).
34
fn bsig0(a: u32) -> u32 {
35
    return rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
36
}
37
38
/// SHA-256 big sigma 1: rotr(e, 6) XOR rotr(e, 11) XOR rotr(e, 25).
39
fn bsig1(e: u32) -> u32 {
40
    return rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
41
}
42
43
/// SHA-256 small sigma 0: rotr(x, 7) XOR rotr(x, 18) XOR (x >> 3).
44
fn ssig0(x: u32) -> u32 {
45
    return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
46
}
47
48
/// SHA-256 small sigma 1: rotr(x, 17) XOR rotr(x, 19) XOR (x >> 10).
49
fn ssig1(x: u32) -> u32 {
50
    return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
51
}
52
53
/// Prepare the message schedule from a 16-word (512-bit) block.
54
fn prepareSchedule(s: *mut Sha256, block: *[u32]) {
55
    // Copy the first 16 words directly.
56
    let mut i: u32 = 0;
57
    while i < 16 {
58
        s.w[i] = block[i];
59
        i += 1;
60
    }
61
    // Extend to 64 words.
62
    while i < 64 {
63
        s.w[i] = ssig1(s.w[i - 2]) + s.w[i - 7] + ssig0(s.w[i - 15]) + s.w[i - 16];
64
        i += 1;
65
    }
66
}
67
68
/// Run the 64-round compression function.
69
fn compress(s: *mut Sha256, k: *[u32]) {
70
    let mut a: u32 = s.h[0];
71
    let mut b: u32 = s.h[1];
72
    let mut c: u32 = s.h[2];
73
    let mut d: u32 = s.h[3];
74
    let mut e: u32 = s.h[4];
75
    let mut f: u32 = s.h[5];
76
    let mut g: u32 = s.h[6];
77
    let mut hh: u32 = s.h[7];
78
79
    let mut i: u32 = 0;
80
    while i < 64 {
81
        let t1 = hh + bsig1(e) + ch(e, f, g) + k[i] + s.w[i];
82
        let t2 = bsig0(a) + maj(a, b, c);
83
        hh = g;
84
        g = f;
85
        f = e;
86
        e = d + t1;
87
        d = c;
88
        c = b;
89
        b = a;
90
        a = t1 + t2;
91
        i += 1;
92
    }
93
94
    s.h[0] += a;
95
    s.h[1] += b;
96
    s.h[2] += c;
97
    s.h[3] += d;
98
    s.h[4] += e;
99
    s.h[5] += f;
100
    s.h[6] += g;
101
    s.h[7] += hh;
102
}
103
104
/// Reset hash state to initial values.
105
fn resetHash(s: *mut Sha256) {
106
    let mut i: u32 = 0;
107
    while i < 8 {
108
        s.h[i] = INIT_H[i];
109
        i += 1;
110
    }
111
}
112
113
/// Pad and hash a short message (up to 55 bytes, fits in one 512-bit block).
114
fn hashMessage(s: *mut Sha256, k: *[u32], msg: *[u8]) -> i32 {
115
    // The message must fit in a single block (max 55 bytes for 1-block padding).
116
    if msg.len > 55 {
117
        return -1;
118
    }
119
120
    // Build the 64-byte (512-bit) padded block.
121
    let mut blockBytes: [u8; 64] = [0; 64];
122
123
    // Copy message.
124
    let mut i: u32 = 0;
125
    while i < msg.len {
126
        blockBytes[i] = msg[i];
127
        i += 1;
128
    }
129
130
    // Append the 1-bit (0x80).
131
    blockBytes[msg.len] = 0x80;
132
133
    // Append length in bits as big-endian 64-bit integer at the end.
134
    let bitLen: u32 = msg.len * 8;
135
    blockBytes[60] = (bitLen >> 24) as u8;
136
    blockBytes[61] = (bitLen >> 16) as u8;
137
    blockBytes[62] = (bitLen >> 8) as u8;
138
    blockBytes[63] = bitLen as u8;
139
140
    // Convert bytes to 16 big-endian 32-bit words.
141
    let mut block: [u32; 16] = [0; 16];
142
    let mut w: u32 = 0;
143
    while w < 16 {
144
        let base = w * 4;
145
        block[w] = (blockBytes[base] as u32 << 24)
146
                  | (blockBytes[base + 1] as u32 << 16)
147
                  | (blockBytes[base + 2] as u32 << 8)
148
                  | (blockBytes[base + 3] as u32);
149
        w += 1;
150
    }
151
152
    resetHash(s);
153
    prepareSchedule(s, &block[..]);
154
    compress(s, k);
155
156
    return 0;
157
}
158
159
/// Test SHA-256 of the empty string "".
160
/// Expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
161
fn testEmpty(s: *mut Sha256, k: *[u32]) -> i32 {
162
    assert hashMessage(s, k, &[]) == 0;
163
164
    assert s.h[0] == 0xE3B0C442;
165
    assert s.h[1] == 0x98FC1C14;
166
    assert s.h[2] == 0x9AFBF4C8;
167
    assert s.h[3] == 0x996FB924;
168
    assert s.h[4] == 0x27AE41E4;
169
    assert s.h[5] == 0x649B934C;
170
    assert s.h[6] == 0xA495991B;
171
    assert s.h[7] == 0x7852B855;
172
    return 0;
173
}
174
175
/// Test SHA-256 of "abc".
176
/// Expected: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
177
fn testAbc(s: *mut Sha256, k: *[u32]) -> i32 {
178
    let msg: [u8; 3] = [0x61, 0x62, 0x63];
179
    assert hashMessage(s, k, &msg[..]) == 0;
180
181
    assert s.h[0] == 0xBA7816BF;
182
    assert s.h[1] == 0x8F01CFEA;
183
    assert s.h[2] == 0x414140DE;
184
    assert s.h[3] == 0x5DAE2223;
185
    assert s.h[4] == 0xB00361A3;
186
    assert s.h[5] == 0x96177A9C;
187
    assert s.h[6] == 0xB410FF61;
188
    assert s.h[7] == 0xF20015AD;
189
    return 0;
190
}
191
192
/// Test the helper functions directly.
193
fn testHelpers() -> i32 {
194
    // rotr(1, 1) should be 0x80000000
195
    assert rotr(1, 1) == 0x80000000;
196
    // rotr(0xFF000000, 8) should be 0x00FF0000
197
    assert rotr(0xFF000000, 8) == 0x00FF0000;
198
    // ch(0xFF, 0x0F, 0xF0):
199
    //   0xFF & 0x0F = 0x0F
200
    //   ~0xFF = 0xFFFFFF00, & 0xF0 = 0x00
201
    //   result = 0x0F ^ 0x00 = 0x0F
202
    assert ch(0xFF, 0x0F, 0xF0) == 0x0F;
203
    // maj(0xFF, 0x0F, 0xF0):
204
    //   0xFF & 0x0F = 0x0F
205
    //   0xFF & 0xF0 = 0xF0
206
    //   0x0F & 0xF0 = 0x00
207
    //   result = 0x0F ^ 0xF0 ^ 0x00 = 0xFF
208
    assert maj(0xFF, 0x0F, 0xF0) == 0xFF;
209
    return 0;
210
}
211
212
@default fn main() -> i32 {
213
    // SHA-256 round constants (first 32 bits of fractional parts of cube roots
214
    // of the first 64 primes).
215
    let k: [u32; 64] = [
216
        0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
217
        0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
218
        0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
219
        0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
220
        0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
221
        0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
222
        0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
223
        0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
224
        0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
225
        0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
226
        0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
227
        0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
228
        0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
229
        0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
230
        0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
231
        0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
232
    ];
233
234
    let mut s: Sha256 = Sha256 { h: INIT_H, w: [0; 64] };
235
236
    let r1 = testHelpers();
237
    if r1 != 0 {
238
        return 10 + r1;
239
    }
240
241
    let r2 = testEmpty(&mut s, &k[..]);
242
    if r2 != 0 {
243
        return 20 + r2;
244
    }
245
246
    let r3 = testAbc(&mut s, &k[..]);
247
    if r3 != 0 {
248
        return 30 + r3;
249
    }
250
    return 0;
251
}