Skip to content

Commit 9e91570

Browse files
align authorize/deactivate/merge/move/split/lockup with native; tighten wire parity + Pinocchio compliance
1 parent b6e84b7 commit 9e91570

31 files changed

Lines changed: 50369 additions & 3172 deletions

instructions_dump.txt

Lines changed: 0 additions & 2690 deletions
This file was deleted.

program/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ bincode = "1"
3535

3636
[features]
3737
# Build for the chain (SBF, no_std, real entrypoint, panic handler)
38-
sbf = ["bpf-entrypoint", "wire_bincode"]
38+
sbf = ["bpf-entrypoint", "wire_bincode", "compat_derivation_fallback"]
3939

4040
# Controls the entrypoint module inclusion
4141
bpf-entrypoint = []
@@ -46,7 +46,8 @@ std = ["bincode"]
4646

4747
# Default host/dev: std + NO entrypoint (keeps IDE/cargo happy)
4848
default = ["std", "no-entrypoint", "wire_bincode"]
49-
e2e = ["allow-uninitialized-split"]
49+
e2e = ["allow-uninitialized-split", "compat_derivation_fallback", "compat_loose_decode"]
50+
compat_derivation_fallback = []
5051
seed = []
5152
cu-trace = []
5253
wire_bincode = []

program/benchmarks/current.csv

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +0,0 @@
1-
name,pin,native
2-
initialize_checked,651,5089
3-
authorize_checked,1417,9148
4-
set_lockup_checked,1367,8505
5-
delegate,1005,12565
6-
deactivate,917,10643
7-
split,2270,16048
8-
withdraw,827,5644
9-
merge,2834,9274
10-
move_lamports,3668,8689
11-
get_minimum_delegation,429,676

program/src/crypto/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod sha256;
2+

program/src/crypto/sha256.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#![allow(clippy::needless_range_loop)]
2+
3+
use core::convert::TryInto;
4+
5+
const H0: [u32; 8] = [
6+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
7+
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
8+
];
9+
10+
const K: [u32; 64] = [
11+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
12+
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
13+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
14+
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
15+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
16+
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
17+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
18+
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
19+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
20+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
21+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
22+
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
23+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
24+
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
25+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
26+
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
27+
];
28+
29+
#[inline(always)]
30+
fn rotr(x: u32, n: u32) -> u32 { (x >> n) | (x << (32 - n)) }
31+
#[inline(always)]
32+
fn ch(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (!x & z) }
33+
#[inline(always)]
34+
fn maj(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (x & z) ^ (y & z) }
35+
#[inline(always)]
36+
fn big_sigma0(x: u32) -> u32 { rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22) }
37+
#[inline(always)]
38+
fn big_sigma1(x: u32) -> u32 { rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25) }
39+
#[inline(always)]
40+
fn small_sigma0(x: u32) -> u32 { rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3) }
41+
#[inline(always)]
42+
fn small_sigma1(x: u32) -> u32 { rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10) }
43+
44+
// Hash arbitrary bytes using SHA-256 (no_std, small, 64-byte blocks)
45+
pub fn hash(data: &[u8]) -> [u8; 32] {
46+
let bit_len: u64 = (data.len() as u64) * 8;
47+
// Padded length: data + 1 + pad + 8, multiple of 64. Our inputs are small; cap to 3 blocks.
48+
let mut padded = [0u8; 192];
49+
let mut plen = 0usize;
50+
51+
// Copy data
52+
padded[..data.len()].copy_from_slice(data);
53+
plen = data.len();
54+
// Append 0x80
55+
padded[plen] = 0x80; plen += 1;
56+
// Compute zero pad so that there are 8 bytes left in the final block
57+
let rem = plen % 64;
58+
let pad_zeros = if rem <= 56 { 56 - rem } else { 64 + 56 - rem };
59+
for i in 0..pad_zeros { padded[plen + i] = 0; }
60+
plen += pad_zeros;
61+
// Append length in bits (big-endian)
62+
let len_bytes = bit_len.to_be_bytes();
63+
padded[plen..plen + 8].copy_from_slice(&len_bytes);
64+
plen += 8;
65+
66+
// Initialize hash state
67+
let mut h = H0;
68+
let mut w = [0u32; 64];
69+
70+
// Process each 64-byte block
71+
for chunk in padded[..plen].chunks_exact(64) {
72+
// Prepare message schedule
73+
for t in 0..16 {
74+
let i = t * 4;
75+
w[t] = u32::from_be_bytes(chunk[i..i + 4].try_into().unwrap());
76+
}
77+
for t in 16..64 {
78+
w[t] = small_sigma1(w[t - 2])
79+
.wrapping_add(w[t - 7])
80+
.wrapping_add(small_sigma0(w[t - 15]))
81+
.wrapping_add(w[t - 16]);
82+
}
83+
84+
// Initialize working variables
85+
let (mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut hh) =
86+
(h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]);
87+
88+
// Main compression
89+
for t in 0..64 {
90+
let t1 = hh
91+
.wrapping_add(big_sigma1(e))
92+
.wrapping_add(ch(e, f, g))
93+
.wrapping_add(K[t])
94+
.wrapping_add(w[t]);
95+
let t2 = big_sigma0(a).wrapping_add(maj(a, b, c));
96+
hh = g;
97+
g = f;
98+
f = e;
99+
e = d.wrapping_add(t1);
100+
d = c;
101+
c = b;
102+
b = a;
103+
a = t1.wrapping_add(t2);
104+
}
105+
106+
// Update hash state
107+
h[0] = h[0].wrapping_add(a);
108+
h[1] = h[1].wrapping_add(b);
109+
h[2] = h[2].wrapping_add(c);
110+
h[3] = h[3].wrapping_add(d);
111+
h[4] = h[4].wrapping_add(e);
112+
h[5] = h[5].wrapping_add(f);
113+
h[6] = h[6].wrapping_add(g);
114+
h[7] = h[7].wrapping_add(hh);
115+
}
116+
117+
// Produce output (big-endian)
118+
let mut out = [0u8; 32];
119+
for (i, v) in h.iter().enumerate() {
120+
out[i * 4..i * 4 + 4].copy_from_slice(&v.to_be_bytes());
121+
}
122+
out
123+
}
124+

0 commit comments

Comments
 (0)