mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
bump package id component to 32 bits
and to make the base64 round even, bump sha256 to 200 bits (up from 192)
This commit is contained in:
parent
0fc7c9f57c
commit
ea516f0e81
4 changed files with 26 additions and 27 deletions
|
|
@ -12,5 +12,5 @@
|
|||
},
|
||||
},
|
||||
.paths = .{""},
|
||||
.nonce = 0xc1ce10810000f013,
|
||||
.nonce = 0xc1ce108124179e16,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@ Zig package namespace.
|
|||
|
||||
Must be a valid bare Zig identifier (don't `@` me), limited to 32 bytes.
|
||||
|
||||
Together with `nonce`, this represents a globally unique package identifier.
|
||||
|
||||
### `nonce`
|
||||
|
||||
Together with name, this represents a globally unique package identifier. This
|
||||
Together with `name`, this represents a globally unique package identifier. This
|
||||
field is auto-initialized by the toolchain when the package is first created,
|
||||
and then *never changes*. This allows Zig to unambiguously detect when one
|
||||
package is an updated version of another.
|
||||
|
|
@ -34,14 +36,14 @@ project is still maintained. Otherwise, the fork is *hostile*, attempting to
|
|||
take control over the original project's identity. The nonce can be regenerated
|
||||
by deleting the field and running `zig build`.
|
||||
|
||||
This 64-bit integer is the combination of a 16-bit id component, a 32-bit
|
||||
checksum, and 16 bits of reserved zeroes.
|
||||
This 64-bit integer is the combination of a 32-bit id component and a 32-bit
|
||||
checksum.
|
||||
|
||||
The id component within the nonce has these restrictions:
|
||||
|
||||
`0x0000` is reserved for legacy packages.
|
||||
`0x00000000` is reserved for legacy packages.
|
||||
|
||||
`0xffff` is reserved to represent "naked" packages.
|
||||
`0xffffffff` is reserved to represent "naked" packages.
|
||||
|
||||
The checksum is computed from `name` and serves to protect Zig users from
|
||||
accidental id collisions.
|
||||
|
|
|
|||
|
|
@ -11,20 +11,19 @@ pub const multihash_hex_digest_len = 2 * multihash_len;
|
|||
pub const MultiHashHexDigest = [multihash_hex_digest_len]u8;
|
||||
|
||||
pub const Nonce = packed struct(u64) {
|
||||
id: u16,
|
||||
reserved: u16 = 0,
|
||||
id: u32,
|
||||
checksum: u32,
|
||||
|
||||
pub fn generate(name: []const u8) Nonce {
|
||||
return .{
|
||||
.id = std.crypto.random.intRangeLessThan(u16, 0x0001, 0xffff),
|
||||
.id = std.crypto.random.intRangeLessThan(u32, 1, 0xffffffff),
|
||||
.checksum = std.hash.Crc32.hash(name),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn validate(n: Nonce, name: []const u8) bool {
|
||||
switch (n.id) {
|
||||
0x0000, 0xffff => return false,
|
||||
0x00000000, 0xffffffff => return false,
|
||||
else => return std.hash.Crc32.hash(name) == n.checksum,
|
||||
}
|
||||
}
|
||||
|
|
@ -54,8 +53,8 @@ pub const Hash = struct {
|
|||
pub const Algo = std.crypto.hash.sha2.Sha256;
|
||||
pub const Digest = [Algo.digest_length]u8;
|
||||
|
||||
/// Example: "nnnn-vvvv-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
|
||||
pub const max_len = 32 + 1 + 32 + 1 + (16 + 32 + 192) / 6;
|
||||
/// Example: "nnnn-vvvv-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
|
||||
pub const max_len = 32 + 1 + 32 + 1 + (32 + 32 + 200) / 6;
|
||||
|
||||
pub fn fromSlice(s: []const u8) Hash {
|
||||
assert(s.len <= max_len);
|
||||
|
|
@ -96,14 +95,12 @@ pub const Hash = struct {
|
|||
/// bytes and assumed be a valid zig identifier
|
||||
/// * semver is the version field from build.zig.zon, asserted to be at
|
||||
/// most 32 bytes
|
||||
/// * hashplus is the following 39-byte array, base64 encoded using -_ to make
|
||||
/// * hashplus is the following 33-byte array, base64 encoded using -_ to make
|
||||
/// it filesystem safe:
|
||||
/// - (2 bytes) LE u16 Package ID
|
||||
/// - (4 bytes) LE u32 Package ID
|
||||
/// - (4 bytes) LE u32 total decompressed size in bytes, overflow saturated
|
||||
/// - (24 bytes) truncated SHA-256 digest of hashed files of the package
|
||||
///
|
||||
/// example: "nasm-2.16.1-3-AAD_ZlwACpGU-c3QXp_yNyn07Q5U9Rq-Cb1ur2G1"
|
||||
pub fn init(digest: Digest, name: []const u8, ver: []const u8, id: u16, size: u32) Hash {
|
||||
/// - (25 bytes) truncated SHA-256 digest of hashed files of the package
|
||||
pub fn init(digest: Digest, name: []const u8, ver: []const u8, id: u32, size: u32) Hash {
|
||||
assert(name.len <= 32);
|
||||
assert(ver.len <= 32);
|
||||
var result: Hash = undefined;
|
||||
|
|
@ -112,11 +109,11 @@ pub const Hash = struct {
|
|||
buf.appendAssumeCapacity('-');
|
||||
buf.appendSliceAssumeCapacity(ver);
|
||||
buf.appendAssumeCapacity('-');
|
||||
var hashplus: [30]u8 = undefined;
|
||||
std.mem.writeInt(u16, hashplus[0..2], id, .little);
|
||||
std.mem.writeInt(u32, hashplus[2..6], size, .little);
|
||||
hashplus[6..].* = digest[0..24].*;
|
||||
_ = std.base64.url_safe_no_pad.Encoder.encode(buf.addManyAsArrayAssumeCapacity(40), &hashplus);
|
||||
var hashplus: [33]u8 = undefined;
|
||||
std.mem.writeInt(u32, hashplus[0..4], id, .little);
|
||||
std.mem.writeInt(u32, hashplus[4..8], size, .little);
|
||||
hashplus[8..].* = digest[0..25].*;
|
||||
_ = std.base64.url_safe_no_pad.Encoder.encode(buf.addManyAsArrayAssumeCapacity(44), &hashplus);
|
||||
@memset(buf.unusedCapacitySlice(), 0);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -194,8 +191,8 @@ test Hash {
|
|||
0xc7, 0xf5, 0x71, 0xb7, 0xb4, 0xe7, 0x6f, 0x3c, 0xdb, 0x87, 0x7a, 0x7f, 0xdd, 0xf9, 0x77, 0x87,
|
||||
0x9d, 0xd3, 0x86, 0xfa, 0x73, 0x57, 0x9a, 0xf7, 0x9d, 0x1e, 0xdb, 0x8f, 0x3a, 0xd9, 0xbd, 0x9f,
|
||||
};
|
||||
const result: Hash = .init(example_digest, "nasm", "2.16.1-2", 0xcafe, 10 * 1024 * 1024);
|
||||
try std.testing.expectEqualStrings("nasm-2.16.1-2-_soAAKAAx_Vxt7Tnbzzbh3p_3fl3h53ThvpzV5r3", result.toSlice());
|
||||
const result: Hash = .init(example_digest, "nasm", "2.16.1-3", 0xcafebabe, 10 * 1024 * 1024);
|
||||
try std.testing.expectEqualStrings("nasm-2.16.1-3-vrr-ygAAoADH9XG3tOdvPNuHen_d-XeHndOG-nNXmved", result.toSlice());
|
||||
}
|
||||
|
||||
test {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub const ErrorMessage = struct {
|
|||
};
|
||||
|
||||
name: []const u8,
|
||||
id: u16,
|
||||
id: u32,
|
||||
version: std.SemanticVersion,
|
||||
version_node: Ast.Node.Index,
|
||||
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
|
||||
|
|
@ -149,7 +149,7 @@ const Parse = struct {
|
|||
errors: std.ArrayListUnmanaged(ErrorMessage),
|
||||
|
||||
name: []const u8,
|
||||
id: u16,
|
||||
id: u32,
|
||||
version: std.SemanticVersion,
|
||||
version_node: Ast.Node.Index,
|
||||
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue