Skip to content

Commit

Permalink
feat: support multihash as schema in zenroom given
Browse files Browse the repository at this point in the history
this is now able to import a generic multihash type and recognize it
from its prefixes, it also operates some checks, then sets the schema
accordingly for the output. Given input can be specified or left
generic, then is autodetected.
  • Loading branch information
jaromil committed Jan 29, 2025
1 parent d8f07a8 commit 5ce95f1
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 21 deletions.
19 changes: 14 additions & 5 deletions src/lua/zencode_given.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ function operate_conversion(guessed)
error("Could not read " .. guessed.name)
end
end
-- fun may return two values: val and optional param
-- which is used in ack() to set additional CODEC params
-- param is defined directly into the schema function!
return fun(guessed.raw)
end
end
Expand Down Expand Up @@ -248,14 +251,20 @@ local function ack(what)
local name <const> = _index_to_string(what)
zencode_assert(t, 'No valid object found: ' .. name)
empty(name)
local v <const> = operate_conversion(t)
ACK[name] = v
-- get value and optional additional parameters for codec
local val <const>, param <const> = operate_conversion(t)
ACK[name] = val
if not CODEC[name].missing then
local vt <const> = type(v)
if iszen(vt) then
CODEC[name].bintype = vt
local valtype <const> = type(val)
if iszen(valtype) then
CODEC[name].bintype = valtype
end
end
if param then
for k,v in pairs(param) do
CODEC[name][k] = v
end
end
-- name of schema may differ from name of object
-- new_codec(name, { schema = ZEN.TMP.schema })

Expand Down
92 changes: 76 additions & 16 deletions src/lua/zencode_hash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ end
When("create hash of ''", _hash)
When("create hash of '' using ''", _hash)

-- global used by _mhout and _mhin
local multihash_prefixes <const> = {
sha256 = OCTET.from_hex'12',
sha512 = OCTET.from_hex'13',
sha3_512 = OCTET.from_hex'14',
sha3_256 = OCTET.from_hex'16',
shake_256 = OCTET.from_hex'19',
keccak_256 = OCTET.from_hex'1b'
}

--https://github.com/multiformats/multicodec/blob/master/table.cs
local function _multihash(n, obj)
local prefix <const> = {
sha256 = OCTET.from_hex'12',
sha512 = OCTET.from_hex'13',
sha3_512 = OCTET.from_hex'14',
sha3_256 = OCTET.from_hex'16',
shake_256 = OCTET.from_hex'19',
keccak_256 = OCTET.from_hex'1b'
}
local function _mhout(n, obj)
local _size <const> = {
sha256 = OCTET.from_number(32):copy(15,1),
sha512 = OCTET.from_number(64):copy(15,1),
Expand All @@ -66,20 +68,78 @@ local function _multihash(n, obj)
shake_256 = OCTET.from_number(32):copy(15,1),
keccak_256 = OCTET.from_number(32):copy(15,1)
}
local pfx <const> = prefix[n]
local pfx <const> = multihash_prefixes[n]
local sz <const> = _size[n]
if not pfx then error("Multihash not supported: "..n,2) end
if not sz then error("Multihash not supported: "..n,2) end
return pfx..sz..obj
end

local function _mhin(string_obj,hashtype)
if not type(string_obj) == 'string' then
error("Multihash invalid input: "..type(string_obj),3)
end
local obj <const> = CONF.input.encoding.fun(string_obj)
local prefixes <const> = {
['12'] = 'sha256',
['13'] = 'sha512',
['14'] = 'sha3_512',
['16'] = 'sha3_256',
['19'] = 'shake_256',
['1b'] = 'keccak_256'
}
local _pfx
local firstbyte <const> = obj:copy(0,1)
if hashtype then
_pfx = multihash_prefixes[hashtype]
if not _pfx then
error("Multihash not supported: "..hashtype,2) end
if firstbyte ~= _pfx then
error("Incorrect multihash found: "
..firstbyte:hex(),2) end
_pfx = hashtype
else
_pfx = prefixes[firstbyte:hex()]
end
if not _pfx then
error("Multihash not supported: ".._pfx,2) end
local sz <const> = tonumber(obj:copy(1,1):hex(),16)
if #obj ~= sz+2 then
error("Multihash invalid size: "..#obj,2) end
-- return additional params for the codec
return obj:copy(2,sz), {schema='multihash_'.._pfx}
end

ZEN:add_schema({
multihash_sha256 ={export=function(obj) return _multihash('sha256',obj) end},
multihash_sha512 ={export=function(obj) return _multihash('sha512',obj) end},
multihash_sha3_256 ={export=function(obj) return _multihash('sha3_256',obj) end},
multihash_sha3_512 ={export=function(obj) return _multihash('sha3_512',obj) end},
multihash_shake256 ={export=function(obj) return _multihash('shake_256',obj) end},
multihash_keccak256={export=function(obj) return _multihash('keccak_256',obj) end}
multihash = {
import=function(obj) return _mhin(obj) end,
export=function(obj)
error("Invalid multihash value",2) end
},
multihash_sha256 ={
import=function(obj) return _mhin(obj,'sha256') end,
export=function(obj) return _mhout('sha256',obj) end
},
multihash_sha512 ={
import=function(obj) return _mhin(obj,'sha512') end,
export=function(obj) return _mhout('sha512',obj) end
},
multihash_sha3_256 ={
import=function(obj) return _mhin(obj,'sha3_256') end,
export=function(obj) return _mhout('sha3_256',obj) end
},
multihash_sha3_512 ={
import=function(obj) return _mhin(obj,'sha3_512') end,
export=function(obj) return _mhout('sha3_512',obj) end
},
multihash_shake256 ={
import=function(obj) return _mhin(obj,'shake_256') end,
export=function(obj) return _mhout('shake_256',obj) end
},
multihash_keccak256={
import=function(obj) return _mhin(obj,'keccak_256') end,
export=function(obj) return _mhout('keccak_256',obj) end
}
})
When("create multihash of ''",
function(s)
Expand Down
29 changes: 29 additions & 0 deletions test/zencode/hash.bats
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,32 @@ EOF
assert_output '{"multihash":"144098a2d34ebb5ab5452cc6211efd99715942c75210d0ee91f7e8897f777d2aed668c8dd9f7b52042b44514dc282e7c6b4da9c5e21ea14ef259ac29579918d4869d"}'
}

@test "Given I have a 'multihash'" {
cat << EOF > multihash_input.json
{"multihash":"144098a2d34ebb5ab5452cc6211efd99715942c75210d0ee91f7e8897f777d2aed668c8dd9f7b52042b44514dc282e7c6b4da9c5e21ea14ef259ac29579918d4869d"}
EOF
cat <<EOF | zexe multihash_input.zen multihash_input.json
rule output encoding hex
rule input encoding hex
Given I have a 'multihash'
and debug
Then print the 'multihash'
EOF
save_output 'multihash_input_3_512.json'
assert_output '{"multihash":"144098a2d34ebb5ab5452cc6211efd99715942c75210d0ee91f7e8897f777d2aed668c8dd9f7b52042b44514dc282e7c6b4da9c5e21ea14ef259ac29579918d4869d"}'
}

@test "Given I have a 'multihash_sha3_512'" {
cat << EOF > multihash_3_512_input.json
{"multihash_sha3_512":"144098a2d34ebb5ab5452cc6211efd99715942c75210d0ee91f7e8897f777d2aed668c8dd9f7b52042b44514dc282e7c6b4da9c5e21ea14ef259ac29579918d4869d"}
EOF
cat <<EOF | zexe multihash_3_512_input.zen multihash_3_512_input.json
rule output encoding hex
rule input encoding hex
Given I have a 'multihash sha3 512'
and debug
Then print the 'multihash sha3 512'
EOF
save_output 'multihash_defined_input_3_512.json'
assert_output '{"multihash_sha3_512":"144098a2d34ebb5ab5452cc6211efd99715942c75210d0ee91f7e8897f777d2aed668c8dd9f7b52042b44514dc282e7c6b4da9c5e21ea14ef259ac29579918d4869d"}'
}

0 comments on commit 5ce95f1

Please sign in to comment.