/jcs

A pure Elixir implementation of RFC 8785: JSON Canonicalization Scheme (JCS)

Primary LanguageElixirApache License 2.0Apache-2.0

Jcs

A pure Elixir implementation of RFC 8785: JSON Canonicalization Scheme (JCS).

JCS can be used to establish a canonical deterministic representation of linked JSON data. These represenations can then be used in establishing identity proofs.

For an example, see the W3C Data Integrity 1.0 report.

That report also gives as an example usage identity proofs, the ability to authenticate as an entity identified by a Decentralized Identifier (DID).

The JSON encoding here is probably orders of magnitude slower than the Jason library. There is no attempt here to decent better memory management in building the output, and sorting object properties based on their UTF-16-encoded keys can probably be greatly improved also.

Pull requests are gratefully encouraged!

Code is based on the Python 3 jcs package.

Test suites are from the Java implementation by Samuel Erdtman and from Appendix B of RFC 8785.

Installation

If available in Hex, the package can be installed by adding jcs to your list of dependencies in mix.exs:

def deps do
  [
    {:jcs, "~> 0.1.1"}
  ]
end

Usage

Jcs.encode(%{"aa" => 200, "b" => 100.0, "西葛西駅" => [200, "station"], "a" => "hello\tworld!"})
  
"{\"a\":\"hello\\tworld!\",\"aa\":200,\"b\":100,\"西葛西駅\":[200,\"station\"]}"

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/jcs.

Notes on encoding floating point values

This library depends on using the Ryu algorithm that was added to Erlang in OTP 25, via the :erlang.float_to_binary/2 function and the new :short option. See https://www.erlang.org/blog/my-otp-25-highlights/#new-option-short-for-erlangfloat_to_list2-and-erlangfloat_to_binary2 for more information.

Also note that while the RFC states that the Ryu algorithm is compliant for encoding floats, the Erlang implementation encodes integral values like 1e+23 as "1.0e23", where as RFC 8785 would encode this as "1e+23".

When attempting to handle all the test cases in the RFC appendix, it appears as though not all of the IEEE754 double value examples are able to be encoded into Elixir floats. These are commented out as "Elixir can not set this value" in the JcsNumbersTest test module.