diff --git a/README.md b/README.md index e91d104..367c673 100644 --- a/README.md +++ b/README.md @@ -9,23 +9,23 @@ Start by selecting the encoder or decoder for your configuration. These are defi RFC 4648 specifies multiple alphabets, including the [standard Base 64 Alphabet](https://datatracker.ietf.org/doc/html/rfc4648#section-4) known as `base64` and the ["URL and Filename Safe Alphabet"](https://datatracker.ietf.org/doc/html/rfc4648#section-5) known as `base64url`. It also specifies that [padding](https://datatracker.ietf.org/doc/html/rfc4648#section-3.2) should be required in the general case but can be explicitly omitted as an option. Available encoder configurations: -- `BASE64_ENCODER_STANDARD`: uses the standard alphabet (base64) and adds padding. -- `BASE64_ENCODER_STANDARD_NO_PAD`: uses the standard alphabet (base64), but omits padding. -- `BASE64_ENCODER_URL_SAFE`: uses the "URL and Filename Safe Alphabet" (base64url) and adds padding. -- `BASE64_ENCODER_URL_SAFE_NO_PAD`: uses the "URL and Filename Safe Alphabet" (base64url), but omits padding. +- `BASE64_ENCODER`: uses the standard alphabet (base64) and adds padding. +- `BASE64_NO_PAD_ENCODER`: uses the standard alphabet (base64), but omits padding. +- `BASE64_URL_ENCODER`: uses the "URL and Filename Safe Alphabet" (base64url) and omits padding, which is common for `base64url` when the length is implicitly known, as in this case. +- `BASE64_URL_WITH_PAD_ENCODER`: uses the "URL and Filename Safe Alphabet" (base64url) and adds padding. Available decoder configurations: -- `BASE64_DECODER_STANDARD`: uses the standard alphabet (base64) and expects correct padding. -- `BASE64_DECODER_STANDARD_NO_PAD`: uses the standard alphabet (base64), but expects all padding characters to have been stripped. A padding character encoutered during decoding will trigger an error. -- `BASE64_DECODER_URL_SAFE`: uses the "URL and Filename Safe Alphabet" (base64url) and expects correct padding. -- `BASE64_DECODER_URL_SAFE_NO_PAD`: uses the "URL and Filename Safe Alphabet" (base64url), but expects all padding characters to have been stripped. A padding character encoutered during decoding will trigger an error. +- `BASE64_DECODER`: uses the standard alphabet (base64) and expects correct padding. +- `BASE64_NO_PAD_DECODER`: uses the standard alphabet (base64), but expects all padding characters to have been stripped, which is common for `base64url` when the length is implicitly known, as in this case. A padding character encountered during decoding will trigger an error. +- `BASE64_URL_DECODER`: uses the "URL and Filename Safe Alphabet" (base64url), but expects all padding characters to have been stripped. A padding character encountered during decoding will trigger an error. +- `BASE64_URL_WITH_PAD_DECODER`: uses the "URL and Filename Safe Alphabet" (base64url) and expects correct padding. ### `fn encode` Takes an arbitrary byte array as input, encodes it in Base64 according to the alphabet and padding rules specified by the configuration, then encodes each Base64 character into UTF-8 to return a byte array representing the Base64 encoding. ``` // bytes: [u8; N] -let base64 = BASE64_ENCODER_STANDARD.encode(bytes); +let base64 = ENCODER_STANDARD.encode(bytes); ``` ### `fn decode` @@ -33,7 +33,7 @@ Takes a utf-8 byte array that encodes a Base64 string and attempts to decoded it ``` // base64: [u8; N] -let bytes = BASE64_DECODER_STANDARD.decode(base64); +let bytes = DECODER_STANDARD.decode(base64); ``` ## Example usage @@ -44,10 +44,10 @@ fn encode_and_decode() { let input: str<88> = "The quick brown fox jumps over the lazy dog, while 42 ravens perch atop a rusty mailbox."; let base64_encoded = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZywgd2hpbGUgNDIgcmF2ZW5zIHBlcmNoIGF0b3AgYSBydXN0eSBtYWlsYm94Lg=="; - let encoded:[u8; 120] = BASE64_ENCODER_STANDARD.encode(input.as_bytes()); + let encoded:[u8; 120] = noir_base64::BASE64_ENCODER.encode(input.as_bytes()); assert(encoded == base64_encoded.as_bytes()); - let decoded: [u8; 88] = BASE64_DECODER_STANDARD.decode(encoded); + let decoded: [u8; 88] = noir_base64::BASE64_DECODER.decode(encoded); assert(decoded == input.as_bytes()); } ``` diff --git a/src/decoder.nr b/src/decoder.nr index a605dab..0553251 100644 --- a/src/decoder.nr +++ b/src/decoder.nr @@ -2,8 +2,8 @@ use super::defaults::BASE64_PADDING_CHAR; pub global STANDARD = Base64DecodeBE::new(true); pub global STANDARD_NO_PAD = Base64DecodeBE::new(false); -pub global URL_SAFE = Base64DecodeBE::base64url(true); -pub global URL_SAFE_NO_PAD = Base64DecodeBE::base64url(false); +pub global URL_SAFE = Base64DecodeBE::base64url(false); +pub global URL_SAFE_WITH_PAD = Base64DecodeBE::base64url(true); global INVALID_VALUE: u8 = 255; struct Base64DecodeBE { @@ -733,11 +733,11 @@ fn test_decode_max_byte() { assert(result == expected); let input: [u8; 4] = [95, 119, 61, 61]; // "_w==" - let result: [u8; 1] = URL_SAFE.decode(input); + let result: [u8; 1] = URL_SAFE_WITH_PAD.decode(input); assert(result == expected); let input: [u8; 2] = [95, 119]; // "_w" - let result: [u8; 1] = URL_SAFE_NO_PAD.decode(input); + let result: [u8; 1] = URL_SAFE.decode(input); assert(result == expected); } @@ -774,11 +774,11 @@ fn test_decode_underscore_with_standard() { } #[test] -fn test_decode_url_safe() { +fn test_decode_url_safe_with_pad() { // test decoding _ and - let input: [u8; 4] = [95, 45, 65, 61]; let expected: [u8; 2] = [255, 224]; - let result: [u8; 2] = URL_SAFE.decode(input); + let result: [u8; 2] = URL_SAFE_WITH_PAD.decode(input); assert(result == expected); } @@ -786,16 +786,16 @@ fn test_decode_url_safe() { #[test(should_fail_with = "DecodeError: invalid symbol 47, offset 0")] fn test_decode_slash_with_url_safe() { // test decoding / and + - let input: [u8; 4] = [47, 43, 65, 61]; + let input: [u8; 3] = [47, 43, 65]; let _: [u8; 2] = URL_SAFE.decode(input); } #[test] -fn test_decode_url_safe_no_pad() { +fn test_decode_url_safe() { // test decoding _ and - let input: [u8; 3] = [95, 45, 65]; let expected: [u8; 2] = [255, 224]; - let result: [u8; 2] = URL_SAFE_NO_PAD.decode(input); + let result: [u8; 2] = URL_SAFE.decode(input); assert(result == expected); } @@ -805,7 +805,7 @@ fn test_decode_url_safe_no_pad_fail_with_padding() { // test decoding _ and - let input: [u8; 4] = [95, 45, 65, 61]; let expected: [u8; 2] = [255, 224]; - let result: [u8; 2] = URL_SAFE_NO_PAD.decode(input); + let result: [u8; 2] = URL_SAFE.decode(input); assert(result == expected); } @@ -821,9 +821,9 @@ fn test_decode_ascii() { assert(result == expected); let result: [u8; 12] = STANDARD_NO_PAD.decode(input); assert(result == expected); - let result: [u8; 12] = URL_SAFE.decode(input); + let result: [u8; 12] = URL_SAFE_WITH_PAD.decode(input); assert(result == expected); - let result: [u8; 12] = URL_SAFE_NO_PAD.decode(input); + let result: [u8; 12] = URL_SAFE.decode(input); assert(result == expected); } @@ -845,9 +845,9 @@ fn test_decode_utf8() { assert(result == expected); let result: [u8; 27] = STANDARD_NO_PAD.decode(input); assert(result == expected); - let result: [u8; 27] = URL_SAFE.decode(input); + let result: [u8; 27] = URL_SAFE_WITH_PAD.decode(input); assert(result == expected); - let result: [u8; 27] = URL_SAFE_NO_PAD.decode(input); + let result: [u8; 27] = URL_SAFE.decode(input); assert(result == expected); } diff --git a/src/encoder.nr b/src/encoder.nr index e381990..c11ab12 100644 --- a/src/encoder.nr +++ b/src/encoder.nr @@ -2,8 +2,8 @@ use super::defaults::BASE64_PADDING_CHAR; pub global STANDARD = Base64EncodeBE::new(true); pub global STANDARD_NO_PAD = Base64EncodeBE::new(false); -pub global URL_SAFE = Base64EncodeBE::base64url(true); -pub global URL_SAFE_NO_PAD = Base64EncodeBE::base64url(false); +pub global URL_SAFE = Base64EncodeBE::base64url(false); +pub global URL_SAFE_WITH_PAD = Base64EncodeBE::base64url(true); struct Base64EncodeBE { // for some reason, if the lookup table is not defined in a struct, access costs are expensive and ROM tables aren't being used :/ @@ -265,11 +265,11 @@ fn test_encode_max_byte() { let expected: [u8; 2] = [47, 119]; // "/w" assert(result == expected); - let result: [u8; 4] = URL_SAFE.encode(input); + let result: [u8; 4] = URL_SAFE_WITH_PAD.encode(input); let expected: [u8; 4] = [95, 119, 61, 61]; // "_w==" assert(result == expected); - let result: [u8; 2] = URL_SAFE_NO_PAD.encode(input); + let result: [u8; 2] = URL_SAFE.encode(input); let expected: [u8; 2] = [95, 119]; // "_w" assert(result == expected); } @@ -286,9 +286,9 @@ fn test_encode_ascii() { assert(result == expected); let result = STANDARD_NO_PAD.encode(input); assert(result == expected); - let result = URL_SAFE.encode(input); + let result = URL_SAFE_WITH_PAD.encode(input); assert(result == expected); - let result = URL_SAFE_NO_PAD.encode(input); + let result = URL_SAFE.encode(input); assert(result == expected); } @@ -310,9 +310,9 @@ fn test_encode_utf8() { assert(result == expected); let result = STANDARD_NO_PAD.encode(input); assert(result == expected); - let result = URL_SAFE.encode(input); + let result = URL_SAFE_WITH_PAD.encode(input); assert(result == expected); - let result = URL_SAFE_NO_PAD.encode(input); + let result = URL_SAFE.encode(input); assert(result == expected); } @@ -420,21 +420,21 @@ fn test_encode_standard() { } #[test] -fn test_encode_url_safe() { +fn test_encode_url_safe_with_pad() { // test encoding to _ and - let input: [u8; 2] = [255, 224]; let expected: [u8; 4] = [95, 45, 65, 61]; - let result: [u8; 4] = URL_SAFE.encode(input); + let result: [u8; 4] = URL_SAFE_WITH_PAD.encode(input); assert(result == expected); } #[test] -fn test_encode_url_safe_no_pad() { +fn test_encode_url_safe() { // test encoding to _ and - let input: [u8; 2] = [255, 224]; let expected: [u8; 3] = [95, 45, 65]; - let result: [u8; 3] = URL_SAFE_NO_PAD.encode(input); + let result: [u8; 3] = URL_SAFE.encode(input); assert(result == expected); } diff --git a/src/lib.nr b/src/lib.nr index 52c830f..aaf1c9e 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -17,14 +17,14 @@ // output string. mod encoder; pub use encoder::{ - STANDARD as BASE64_ENCODER_STANDARD, STANDARD_NO_PAD as BASE64_ENCODER_STANDARD_NO_PAD, - URL_SAFE as BASE64_ENCODER_URL_SAFE, URL_SAFE_NO_PAD as BASE64_ENCODER_URL_SAFE_NO_PAD, + STANDARD as BASE64_ENCODER, STANDARD_NO_PAD as BASE64_NO_PAD_ENCODER, + URL_SAFE as BASE64_URL_ENCODER, URL_SAFE_WITH_PAD as BASE64_URL_WITH_PAD_ENCODER, }; mod decoder; pub use decoder::{ - STANDARD as BASE64_DECODER_STANDARD, STANDARD_NO_PAD as BASE64_DECODER_STANDARD_NO_PAD, - URL_SAFE as BASE64_DECODER_URL_SAFE, URL_SAFE_NO_PAD as BASE64_DECODER_URL_SAFE_NO_PAD, + STANDARD as BASE64_DECODER, STANDARD_NO_PAD as BASE64_NO_PAD_DECODER, + URL_SAFE as BASE64_URL_DECODER, URL_SAFE_WITH_PAD as BASE64_URL_WITH_PAD_DECODER, }; pub(crate) mod defaults { @@ -37,10 +37,10 @@ fn encode_and_decode() { "The quick brown fox jumps over the lazy dog, while 42 ravens perch atop a rusty mailbox."; let base64_encoded = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZywgd2hpbGUgNDIgcmF2ZW5zIHBlcmNoIGF0b3AgYSBydXN0eSBtYWlsYm94Lg=="; - let encoded: [u8; 120] = BASE64_ENCODER_STANDARD.encode(input.as_bytes()); + let encoded: [u8; 120] = BASE64_ENCODER.encode(input.as_bytes()); assert(encoded == base64_encoded.as_bytes()); - let decoded: [u8; 88] = BASE64_DECODER_STANDARD.decode(encoded); + let decoded: [u8; 88] = BASE64_DECODER.decode(encoded); assert(decoded == input.as_bytes()); } @@ -50,9 +50,9 @@ fn encode_and_decode_no_pad() { "The quick brown fox jumps over the lazy dog, while 42 ravens perch atop a rusty mailbox."; let base64_encoded: str<118> = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZywgd2hpbGUgNDIgcmF2ZW5zIHBlcmNoIGF0b3AgYSBydXN0eSBtYWlsYm94Lg"; - let encoded: [u8; 118] = BASE64_ENCODER_STANDARD_NO_PAD.encode(input.as_bytes()); + let encoded: [u8; 118] = BASE64_NO_PAD_ENCODER.encode(input.as_bytes()); assert(encoded == base64_encoded.as_bytes()); - let decoded: [u8; 88] = BASE64_DECODER_STANDARD_NO_PAD.decode(encoded); + let decoded: [u8; 88] = BASE64_NO_PAD_DECODER.decode(encoded); assert(decoded == input.as_bytes()); }