aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base32.zig40
-rw-r--r--src/nkeys.zig18
2 files changed, 33 insertions, 25 deletions
diff --git a/src/base32.zig b/src/base32.zig
index 26622d8..149e5f0 100644
--- a/src/base32.zig
+++ b/src/base32.zig
@@ -7,8 +7,26 @@ pub const Encoder = struct {
7 index: ?usize, 7 index: ?usize,
8 bit_off: u3, 8 bit_off: u3,
9 9
10 fn bitmask(self: *const Self) u8 { 10 pub fn init(buffer: []const u8) Encoder {
11 return @as(u8, 0b11111000) >> self.bit_off; 11 return .{
12 .buffer = buffer,
13 .index = 0,
14 .bit_off = 0,
15 };
16 }
17
18 pub fn calcSize(source_len: usize) usize {
19 const source_len_bits = source_len * 8;
20 return source_len_bits / 5 + (if (source_len_bits % 5 > 0) @as(usize, 1) else 0);
21 }
22
23 pub fn encode(dest: []u8, source: []const u8) []const u8 {
24 const out_len = calcSize(source.len);
25 std.debug.assert(dest.len >= out_len);
26
27 var e = init(source);
28 for (dest) |*b| b.* = e.next() orelse unreachable;
29 return dest[0..out_len];
12 } 30 }
13 31
14 fn n_front_bits(self: *const Self) u3 { 32 fn n_front_bits(self: *const Self) u3 {
@@ -34,7 +52,8 @@ pub const Encoder = struct {
34 // 5 0b00000111 2 0b11100 52 // 5 0b00000111 2 0b11100
35 // 6 0b00000011 3 0b11000 53 // 6 0b00000011 3 0b11000
36 // 7 0b00000001 4 0b10000 54 // 7 0b00000001 4 0b10000
37 const bits = self.buffer[index] & self.bitmask(); 55 const bitmask = @as(u8, 0b11111000) >> self.bit_off;
56 const bits = self.buffer[index] & bitmask;
38 if (self.bit_off >= 4) return @truncate(u5, bits << (self.bit_off - 3)); 57 if (self.bit_off >= 4) return @truncate(u5, bits << (self.bit_off - 3));
39 return @truncate(u5, bits >> (3 - self.bit_off)); 58 return @truncate(u5, bits >> (3 - self.bit_off));
40 } 59 }
@@ -66,10 +85,12 @@ pub const Encoder = struct {
66 return front_bits | back_bits; 85 return front_bits | back_bits;
67 } 86 }
68 87
88 // Returns the corresponding ASCII character for 5 bits of the input.
69 fn char(unencoded: u5) u8 { 89 fn char(unencoded: u5) u8 {
70 return unencoded + (if (unencoded < 26) @as(u8, 'A') else '2' - 26); 90 return unencoded + (if (unencoded < 26) @as(u8, 'A') else '2' - 26);
71 } 91 }
72 92
93 // Returns the next byte of the encoded buffer.
73 pub fn next(self: *Self) ?u8 { 94 pub fn next(self: *Self) ?u8 {
74 const unencoded = self.next_u5() orelse return null; 95 const unencoded = self.next_u5() orelse return null;
75 return char(unencoded); 96 return char(unencoded);
@@ -121,24 +142,11 @@ pub const Decoder = struct {
121 } 142 }
122}; 143};
123 144
124pub fn encodedLen(src_len: usize) usize {
125 const src_len_bits = src_len * 8;
126 return src_len_bits / 5 + (if (src_len_bits % 5 > 0) @as(usize, 1) else 0);
127}
128
129pub fn decodedLen(enc_len: usize) usize { 145pub fn decodedLen(enc_len: usize) usize {
130 const enc_len_bits = enc_len * 5; 146 const enc_len_bits = enc_len * 5;
131 return enc_len_bits / 8; 147 return enc_len_bits / 8;
132} 148}
133 149
134pub fn encode(bs: []const u8, out: []u8) usize {
135 var e = Encoder{ .buffer = bs, .index = 0, .bit_off = 0 };
136 for (out) |*b, i| {
137 b.* = e.next() orelse return i;
138 }
139 return out.len;
140}
141
142pub fn decode(ps: []const u8, out: []u8) DecodeError!usize { 150pub fn decode(ps: []const u8, out: []u8) DecodeError!usize {
143 var d = Decoder{}; 151 var d = Decoder{};
144 var i: usize = 0; 152 var i: usize = 0;
diff --git a/src/nkeys.zig b/src/nkeys.zig
index b8693ae..818fd98 100644
--- a/src/nkeys.zig
+++ b/src/nkeys.zig
@@ -211,9 +211,9 @@ const binary_public_size = 1 + Ed25519.public_length + 2;
211// Two prefix bytes, two CRC bytes 211// Two prefix bytes, two CRC bytes
212const binary_seed_size = 2 + Ed25519.seed_length + 2; 212const binary_seed_size = 2 + Ed25519.seed_length + 2;
213 213
214pub const text_private_len = base32.encodedLen(binary_private_size); 214pub const text_private_len = base32.Encoder.calcSize(binary_private_size);
215pub const text_public_len = base32.encodedLen(binary_public_size); 215pub const text_public_len = base32.Encoder.calcSize(binary_public_size);
216pub const text_seed_len = base32.encodedLen(binary_seed_size); 216pub const text_seed_len = base32.Encoder.calcSize(binary_seed_size);
217 217
218pub const text_private = [text_private_len]u8; 218pub const text_private = [text_private_len]u8;
219pub const text_public = [text_public_len]u8; 219pub const text_public = [text_public_len]u8;
@@ -227,8 +227,8 @@ pub fn encodePrivate(key: *const [Ed25519.secret_length]u8) !text_private {
227 return encode(1, key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, key); 227 return encode(1, key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, key);
228} 228}
229 229
230fn EncodedKey(comptime prefix_len: usize, comptime data_len: usize) type { 230fn encoded_key(comptime prefix_len: usize, comptime data_len: usize) type {
231 return [base32.encodedLen(prefix_len + data_len + 2)]u8; 231 return [base32.Encoder.calcSize(prefix_len + data_len + 2)]u8;
232} 232}
233 233
234fn encode( 234fn encode(
@@ -236,7 +236,7 @@ fn encode(
236 comptime data_len: usize, 236 comptime data_len: usize,
237 prefix: *const [prefix_len]u8, 237 prefix: *const [prefix_len]u8,
238 data: *const [data_len]u8, 238 data: *const [data_len]u8,
239) !EncodedKey(prefix_len, data_len) { 239) !encoded_key(prefix_len, data_len) {
240 var buf: [prefix_len + data_len + 2]u8 = undefined; 240 var buf: [prefix_len + data_len + 2]u8 = undefined;
241 defer wipeBytes(&buf); 241 defer wipeBytes(&buf);
242 242
@@ -246,8 +246,8 @@ fn encode(
246 var checksum = crc16.make(buf[0..off]); 246 var checksum = crc16.make(buf[0..off]);
247 mem.writeIntLittle(u16, buf[buf.len - 2 .. buf.len], checksum); 247 mem.writeIntLittle(u16, buf[buf.len - 2 .. buf.len], checksum);
248 248
249 var text: EncodedKey(prefix_len, data_len) = undefined; 249 var text: encoded_key(prefix_len, data_len) = undefined;
250 std.debug.assert(base32.encode(&buf, &text) == text.len); 250 _ = base32.Encoder.encode(&text, &buf);
251 251
252 return text; 252 return text;
253} 253}
@@ -285,7 +285,7 @@ fn DecodedNKey(comptime prefix_len: usize, comptime data_len: usize) type {
285fn decode( 285fn decode(
286 comptime prefix_len: usize, 286 comptime prefix_len: usize,
287 comptime data_len: usize, 287 comptime data_len: usize,
288 text: *const [base32.encodedLen(prefix_len + data_len + 2)]u8, 288 text: *const [base32.Encoder.calcSize(prefix_len + data_len + 2)]u8,
289) !DecodedNKey(prefix_len, data_len) { 289) !DecodedNKey(prefix_len, data_len) {
290 var raw: [prefix_len + data_len + 2]u8 = undefined; 290 var raw: [prefix_len + data_len + 2]u8 = undefined;
291 defer wipeBytes(&raw); 291 defer wipeBytes(&raw);