1/// This package is based on the Go implementation found here:
2/// https://cs.opensource.google/go/go/+/refs/tags/go1.23.0:src/crypto/hmac/hmac.go
3/// which has the copyright notice:
4/// Copyright 2009 The Go Authors. All rights reserved.
5/// Use of this source code is governed by a BSD-style
6/// license that can be found in the LICENSE file.
7
8///|
9/// `gen_hmac` generates a base64-encoded String representing
10/// the SHA256 signature of the provided `body` using the provided
11/// `client_secret` key.
12pub fn (body : Bytes, client_secret : Bytes) -> String
gen_hmac generates a base64-encoded String representing
the SHA256 signature of the provided body using the provided
client_secret key.
gen_hmac(Bytes
body : Bytes
Bytes, Bytes
client_secret : Bytes
Bytes) -> String
String {
13 let HMAC
h = struct HMAC {
opad: FixedArray[Byte]
ipad: FixedArray[Byte]
outer: Digest
inner: Digest
}
HMAC::(key : Bytes) -> HMAC
new(Bytes
client_secret)
14 for Byte
b in Bytes
body {
15 HMAC
h.Digest
inner.(self : Digest, b : Byte) -> Unit
write writes a byte to the digest.
write(Byte
b)
16 }
17 let FixedArray[Byte]
buf = HMAC
h.(self : HMAC) -> FixedArray[Byte]
sum()
18 (src : FixedArray[Byte], no_padding~ : Bool = ..) -> String
url_encode2str base64-encodes the provided bytes using URL encoding and returns a String.
Setting no_padding=true is used for raw encoding.
Note that standard encoding uses + and / characters whereas URL encoding uses - and _.
Examples:
let b : Bytes = "+/ Hello, δΈη! π"
inspect!(url_encode2str(b.to_fixedarray()), content="Ky8gSGVsbG8sIOS4lueVjCEg8J-MjQ==")
inspect!(url_encode2str(b.to_fixedarray(), no_padding=true), content="Ky8gSGVsbG8sIOS4lueVjCEg8J-MjQ")
@base64.url_encode2str(FixedArray[Byte]
buf)
19}
20
21///|
22priv struct HMAC {
23 FixedArray[Byte]
opad : type FixedArray[A]
FixedArray[Byte
Byte]
24 FixedArray[Byte]
ipad : type FixedArray[A]
FixedArray[Byte
Byte]
25 Digest
outer : struct Digest {
h: FixedArray[UInt]
x: FixedArray[Byte]
mut nx: Int
mut len: UInt64
name: String
}
Digest represents the partial evaluation of a checksum.
Digest
26 Digest
inner : struct Digest {
h: FixedArray[UInt]
x: FixedArray[Byte]
mut nx: Int
mut len: UInt64
name: String
}
Digest represents the partial evaluation of a checksum.
Digest
27}
28
29///|
30fn struct HMAC {
opad: FixedArray[Byte]
ipad: FixedArray[Byte]
outer: Digest
inner: Digest
}
HMAC::(key : Bytes) -> HMAC
new(Bytes
key : Bytes
Bytes) -> struct HMAC {
opad: FixedArray[Byte]
ipad: FixedArray[Byte]
outer: Digest
inner: Digest
}
HMAC {
31 let HMAC
hm = {
32 FixedArray[Byte]
opad: type FixedArray[A]
FixedArray::(len : Int, init : Byte) -> FixedArray[Byte]
Creates a new fixed-size array with the specified length, initializing all
elements with the given value.
Parameters:
length : The length of the array to create. Must be non-negative.
initial_value : The value used to initialize all elements in the array.
Returns a new fixed-size array of type FixedArray[T] with length
elements, where each element is initialized to initial_value.
Throws a panic if length is negative.
Example:
test "FixedArray::make" {
let arr = FixedArray::make(3, 42)
inspect(arr[0], content="42")
inspect(arr.length(), content="3")
}
test "panic FixedArray::make/negative_length" {
ignore(FixedArray::make(-1, 0))
}
WARNING: A common pitfall is creating with the same initial value, for example:
test {
let two_dimension_array = FixedArray::make(10, FixedArray::make(10, 0))
two_dimension_array[0][5] = 10
assert_eq(two_dimension_array[5][5], 10)
}
This is because all the cells reference to the same object (the FixedArray[Int] in this case).
One should use makei() instead which creates an object for each index.
make(Int
block_size, b'\x00'),
33 FixedArray[Byte]
ipad: type FixedArray[A]
FixedArray::(len : Int, init : Byte) -> FixedArray[Byte]
Creates a new fixed-size array with the specified length, initializing all
elements with the given value.
Parameters:
length : The length of the array to create. Must be non-negative.
initial_value : The value used to initialize all elements in the array.
Returns a new fixed-size array of type FixedArray[T] with length
elements, where each element is initialized to initial_value.
Throws a panic if length is negative.
Example:
test "FixedArray::make" {
let arr = FixedArray::make(3, 42)
inspect(arr[0], content="42")
inspect(arr.length(), content="3")
}
test "panic FixedArray::make/negative_length" {
ignore(FixedArray::make(-1, 0))
}
WARNING: A common pitfall is creating with the same initial value, for example:
test {
let two_dimension_array = FixedArray::make(10, FixedArray::make(10, 0))
two_dimension_array[0][5] = 10
assert_eq(two_dimension_array[5][5], 10)
}
This is because all the cells reference to the same object (the FixedArray[Int] in this case).
One should use makei() instead which creates an object for each index.
make(Int
block_size, b'\x00'),
34 Digest
outer: struct Digest {
h: FixedArray[UInt]
x: FixedArray[Byte]
mut nx: Int
mut len: UInt64
name: String
}
Digest represents the partial evaluation of a checksum.
Digest::() -> Digest
Digest::new returns a new, reset Digest, ready to sum.
new(),
35 Digest
inner: struct Digest {
h: FixedArray[UInt]
x: FixedArray[Byte]
mut nx: Int
mut len: UInt64
name: String
}
Digest represents the partial evaluation of a checksum.
Digest::() -> Digest
Digest::new returns a new, reset Digest, ready to sum.
new(),
36 }
37 // If key is too big, hash it.
38 let mut FixedArray[Byte]
key = type FixedArray[A]
FixedArray::(iter : Iter[Byte]) -> FixedArray[Byte]
Creates a new fixed array from an iterator.
Parameters:
iterator : An iterator of type Iter[T] from which elements will be
collected into a fixed array.
Returns a new fixed array containing all elements from the iterator.
Example:
test "FixedArray::from_iter" {
let arr = [1, 2, 3]
let fixed_arr = FixedArray::from_iter(arr.iter())
inspect(fixed_arr, content="[1, 2, 3]")
}
from_iter(Bytes
key.(self : Bytes) -> Iter[Byte]
Creates an iterator over the bytes in the sequence.
Parameters:
bytes : A byte sequence to iterate over.
Returns an iterator that yields each byte in the sequence in order.
Example:
test "Bytes::iter" {
let bytes = Bytes::from_array([b'h', b'i'])
let mut sum = 0
bytes.iter().each(fn(b) { sum = sum + b.to_int() })
inspect(sum, content="209") // ASCII values: 'h'(104) + 'i'(105) = 209
}
iter())
39 if FixedArray[Byte]
key.(self : FixedArray[Byte]) -> Int
Returns the number of elements in a fixed-size array.
Parameters:
array : The fixed-size array whose length is to be determined.
Returns an integer representing the number of elements in the array.
Example:
test "FixedArray::length" {
let arr = FixedArray::make(3, 42)
inspect(arr.length(), content="3")
}
length() (self_ : Int, other : Int) -> Bool
> Int
block_size {
40 for Byte
b in FixedArray[Byte]
key {
41 HMAC
hm.Digest
outer.(self : Digest, b : Byte) -> Unit
write writes a byte to the digest.
write(Byte
b)
42 }
43 FixedArray[Byte]
key = HMAC
hm.Digest
outer.(self : Digest) -> FixedArray[Byte]
sum returns the final sha256sum as a FixedArray[Byte].
sum()
44 }
45 // copy
46 for Int
index, Byte
b in FixedArray[Byte]
key {
47 HMAC
hm.FixedArray[Byte]
ipad(FixedArray[Byte], Int, Byte) -> Unit
Sets a value at the specified index in a fixed-size array. The original value
at that index is overwritten.
Parameters:
array : The fixed-size array to modify.
index : The position in the array where the value will be set.
value : The new value to assign at the specified index.
Throws a runtime error if the index is out of bounds (less than 0 or greater
than or equal to the length of the array).
Example:
test "FixedArray::op_set" {
let arr = [1, 2, 3]
arr[1] = 42
inspect(arr, content="[1, 42, 3]")
}
test "panic FixedArray::op_set/out_of_bounds" {
let arr = [1, 2, 3]
arr[3] = 42 // Index out of bounds
}
[index] = Byte
b
48 HMAC
hm.FixedArray[Byte]
opad(FixedArray[Byte], Int, Byte) -> Unit
Sets a value at the specified index in a fixed-size array. The original value
at that index is overwritten.
Parameters:
array : The fixed-size array to modify.
index : The position in the array where the value will be set.
value : The new value to assign at the specified index.
Throws a runtime error if the index is out of bounds (less than 0 or greater
than or equal to the length of the array).
Example:
test "FixedArray::op_set" {
let arr = [1, 2, 3]
arr[1] = 42
inspect(arr, content="[1, 42, 3]")
}
test "panic FixedArray::op_set/out_of_bounds" {
let arr = [1, 2, 3]
arr[3] = 42 // Index out of bounds
}
[index] = Byte
b
49 }
50 for Int
index, Byte
b in HMAC
hm.FixedArray[Byte]
ipad {
51 HMAC
hm.FixedArray[Byte]
ipad(FixedArray[Byte], Int, Byte) -> Unit
Sets a value at the specified index in a fixed-size array. The original value
at that index is overwritten.
Parameters:
array : The fixed-size array to modify.
index : The position in the array where the value will be set.
value : The new value to assign at the specified index.
Throws a runtime error if the index is out of bounds (less than 0 or greater
than or equal to the length of the array).
Example:
test "FixedArray::op_set" {
let arr = [1, 2, 3]
arr[1] = 42
inspect(arr, content="[1, 42, 3]")
}
test "panic FixedArray::op_set/out_of_bounds" {
let arr = [1, 2, 3]
arr[3] = 42 // Index out of bounds
}
[index] = Byte
b (self : Byte, that : Byte) -> Byte
Performs a bitwise XOR operation between two Byte values.
Parameters:
self : The first Byte value.
that : The second Byte value.
Returns the result of the bitwise XOR operation as a Byte.
^ b'\x36'
52 HMAC
hm.Digest
inner.(self : Digest, b : Byte) -> Unit
write writes a byte to the digest.
write(HMAC
hm.FixedArray[Byte]
ipad(FixedArray[Byte], Int) -> Byte
Retrieves an element at the specified index from a fixed-size array. This
function implements the array indexing operator [].
Parameters:
array : The fixed-size array to access.
index : The position in the array from which to retrieve the element.
Returns the element at the specified index.
Throws a runtime error if the index is out of bounds (negative or greater
than or equal to the length of the array).
Example:
test "FixedArray::op_get" {
let arr = FixedArray::make(3, 42)
inspect(arr[1], content="42")
}
test "panic FixedArray::op_get/out_of_bounds" {
let arr = FixedArray::make(3, 0)
ignore(arr[3]) // Index out of bounds
}
[index])
53 }
54 for Int
index, Byte
b in HMAC
hm.FixedArray[Byte]
opad {
55 HMAC
hm.FixedArray[Byte]
opad(FixedArray[Byte], Int, Byte) -> Unit
Sets a value at the specified index in a fixed-size array. The original value
at that index is overwritten.
Parameters:
array : The fixed-size array to modify.
index : The position in the array where the value will be set.
value : The new value to assign at the specified index.
Throws a runtime error if the index is out of bounds (less than 0 or greater
than or equal to the length of the array).
Example:
test "FixedArray::op_set" {
let arr = [1, 2, 3]
arr[1] = 42
inspect(arr, content="[1, 42, 3]")
}
test "panic FixedArray::op_set/out_of_bounds" {
let arr = [1, 2, 3]
arr[3] = 42 // Index out of bounds
}
[index] = Byte
b (self : Byte, that : Byte) -> Byte
Performs a bitwise XOR operation between two Byte values.
Parameters:
self : The first Byte value.
that : The second Byte value.
Returns the result of the bitwise XOR operation as a Byte.
^ b'\x5c'
56 }
57 HMAC
hm
58}
59
60///|
61fn struct HMAC {
opad: FixedArray[Byte]
ipad: FixedArray[Byte]
outer: Digest
inner: Digest
}
HMAC::(self : HMAC) -> FixedArray[Byte]
sum(HMAC
self : struct HMAC {
opad: FixedArray[Byte]
ipad: FixedArray[Byte]
outer: Digest
inner: Digest
}
HMAC) -> type FixedArray[A]
FixedArray[Byte
Byte] {
62 let FixedArray[Byte]
inner_sum = HMAC
self.Digest
inner.(self : Digest) -> FixedArray[Byte]
sum returns the final sha256sum as a FixedArray[Byte].
sum()
63 HMAC
self.Digest
outer.(self : Digest) -> Unit
reset resets a digest for re-use.
reset()
64 for Byte
b in HMAC
self.FixedArray[Byte]
opad {
65 HMAC
self.Digest
outer.(self : Digest, b : Byte) -> Unit
write writes a byte to the digest.
write(Byte
b)
66 }
67 for Byte
b in FixedArray[Byte]
inner_sum {
68 HMAC
self.Digest
outer.(self : Digest, b : Byte) -> Unit
write writes a byte to the digest.
write(Byte
b)
69 }
70 HMAC
self.Digest
outer.(self : Digest) -> FixedArray[Byte]
sum returns the final sha256sum as a FixedArray[Byte].
sum()
71}
72