src/crypto/secp256k1/bytes.bend source
src/crypto/secp256k1/bytes.bend on the hub · documented module
import Base# Octet strings and 16-bit limbs. Bytes are U32 values; only the low 8 bits# of a byte are read (the library's byte convention keeps them below 256).def byte(+b: U32) -> Nat: U32.to_nat(U32.and(b, 255))# little-endian limbs of little-endian bytes (two bytes per limb)def limbs_le(bs: List<&2, U32>) -> List<&2, Nat>: match bs: case Nil{}: Nil{} case b0 <> Nil{}: [byte(b0)] case b0 <> b1 <> t: Nat.add(Nat.mul(byte(b1), 256n), byte(b0)) <> limbs_le(t)# the 16 limbs of a 32-byte big-endian string (SEC 1 OS2IP)def of_be(bs: List<&2, U32>) -> List<&2, Nat>: limbs_le(List.reverse(&2, U32, bs))# little-endian bytes of limbs below 2^16def bytes_le(xs: List<&2, Nat>) -> List<&2, U32>: match xs: case Nil{}: Nil{} case +x <> t: U32.from_nat(Nat.mod(x, 256n)) <> U32.from_nat(Nat.div(x, 256n)) <> bytes_le(t)# the 32-byte big-endian string of 16 limbs (SEC 1 I2OSP)def to_be(xs: List<&2, Nat>) -> List<&2, U32>: List.reverse(&2, U32, bytes_le(xs))def has_len(n: Nat, bs: List<&2, U32>) -> Bool: match n bs: case 0n Nil{}: True{} case 0n b <> t: False{} case 1n+k Nil{}: False{} case 1n+k b <> t: has_len(k, t)def prefix(n: Nat, bs: List<&2, U32>) -> List<&2, U32>: match n bs: case 0n _: Nil{} case 1n+k Nil{}: Nil{} case 1n+k b <> t: b <> prefix(k, t)def suffix(n: Nat, bs: List<&2, U32>) -> List<&2, U32>: match n bs: case 0n _: bs case 1n+k Nil{}: Nil{} case 1n+k b <> t: suffix(k, t)def head(bs: List<&2, U32>) -> U32: match bs: case Nil{}: 0 case b <> t: bdef tail(bs: List<&2, U32>) -> List<&2, U32>: match bs: case Nil{}: Nil{} case b <> t: t