Compare commits

...

20 Commits

Author SHA1 Message Date
Agorise 3a7a71c7fd
Update LICENSE 2019-01-01 10:37:07 -06:00
Agorise bc6c083013
Update LICENSE 2018-06-17 16:31:24 +03:00
Agorise 961feef19c
Update LICENSE 2017-11-15 13:23:36 +02:00
Agorise 5113883f45 Update LICENSE 2017-10-16 13:58:51 +03:00
jmjatlanta c794c28bbe Added build targets 2017-07-17 16:13:27 -05:00
John Jones bcfc17cc93 Added comment to header 2017-02-13 09:32:55 -05:00
jmjatlanta 59e0c1ae35 minor changes, added const to some params 2016-12-15 12:41:14 -05:00
John Jones cb7be4706c added Eclipse project files 2016-11-17 16:36:56 -05:00
John Jones 4c3c2a59ed Cleaned up Makefile 2016-11-14 08:11:21 -05:00
John Jones f57e928cf8 Clean up 2016-11-10 16:28:51 -05:00
John Jones 5ad6f0d58f removed building of main from makefile 2016-11-10 09:29:42 -05:00
John Jones 904cdf6871 general cleanup 2016-11-07 17:05:49 -05:00
Jakub Sztandera 4e1b3171fb
Fix complication errors 2016-10-23 17:28:49 +02:00
Richard Littauer e5f3069d84 Merge pull request #4 from multiformats/feature/std-md
Standardized Readme
2016-08-15 14:21:40 -04:00
Richard Littauer 78b8365819 Moved to markdown again 2016-08-15 13:19:58 -04:00
Richard Littauer a3a4307365 Capitalized 2016-08-15 13:19:24 -04:00
Jakub Sztandera 67492d05e4
move license to Protocol Labs 2016-08-15 19:07:02 +02:00
Richard Littauer 119ce220ff
Standardized Readme
See https://github.com/multiformats/multiformats/issues/13
2016-08-15 19:04:53 +02:00
Jakub Sztandera 5b03c22dd8
apply most of Jeromy's review 2016-08-15 18:59:03 +02:00
Jakub Sztandera 01aabc6411
add copyright holder to LICENSE 2016-08-15 18:25:04 +02:00
13 changed files with 334 additions and 81 deletions

73
.cproject Normal file
View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.macosx.base.1386600442">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.macosx.base.1386600442" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.macosx.base.1386600442" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.macosx.base.1386600442.1551296983" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.macosx.base.386985440" name="MacOSX GCC" superClass="cdt.managedbuild.toolchain.gnu.macosx.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.MachO64" id="cdt.managedbuild.target.gnu.platform.macosx.base.1885573856" name="Debug Platform" osList="macosx" superClass="cdt.managedbuild.target.gnu.platform.macosx.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.macosx.base.1888590002" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.macosx.base"/>
<tool id="cdt.managedbuild.tool.macosx.c.linker.macosx.base.203162375" name="MacOS X C Linker" superClass="cdt.managedbuild.tool.macosx.c.linker.macosx.base"/>
<tool id="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base.380032459" name="MacOS X C++ Linker" superClass="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base">
<inputType id="cdt.managedbuild.tool.macosx.cpp.linker.input.1178315229" superClass="cdt.managedbuild.tool.macosx.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.macosx.base.2122297325" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.macosx.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.382562785" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.macosx.base.763285879" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.macosx.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base.518702814" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.80838163" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.macosx.base.1842847648" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.macosx.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1789278916" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="c-multihash.null.624575767" name="c-multihash"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

5
.gitignore vendored
View File

@ -3,3 +3,8 @@
!.gitignore
!Makefile
!**/
*.o
*.a
.settings/language.settings.xml

27
.project Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>c-multihash</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -1,6 +1,9 @@
The MIT License (MIT)
Copyright (c) 2016
Copyright (c) 2019 AGORISE, LTD.
An International Business Company, Cyprus Reg# ΗΕ375959
Also contains works from Protocol Labs, Inc. Copyright (c) 2016.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,8 @@
DEBUG=true
CC = gcc
RM = rm -f
CFLAGS = -fPIC -g -O2 -std=c99 \
CFLAGS = -fPIC -O0 -std=c99 \
-Wall -Wextra -pedantic -Werror \
-Wdeclaration-after-statement \
-Wno-format-zero-length \
@ -10,29 +12,27 @@ CFLAGS = -fPIC -g -O2 -std=c99 \
-Wunused \
-Wvla
ifdef DEBUG
CFLAGS += -g3
endif
LDFLAGS = -g
LDLIBS =
TARGET_LIB = mulithash.a
TARGET_LIB = libmultihash.a
TARGET_BIN = multihash
MAIN = src/main.c
MAIN_O = $(MAIN:.c=.o)
SRCS = src/hashes.c src/errors.c src/multihash.c
OBJS = $(SRCS:.c=.o)
src/%.o: src/%.c
$(CC) $(CFLAGS) -c -I include $< -o $@
all: $(TARGET_LIB) $(TARGET_BIN)
all: $(TARGET_LIB)
$(TARGET_LIB): $(OBJS)
ar rcs $@ $^
$(TARGET_BIN): $(MAIN_O) $(TARGET_LIB)
$(CC) $(LDFLAGS) $^ -o $@
# Tests
TEST_SRCS = $(wildcard tests/c/test_*.c)

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# c-multihash
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](http://github.com/multiformats/multiformats)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
> C implementation of Multihash parsing and encoding (but not hashing)
This is an implementation of [multihash](https://github.com/multiformats/multihash).
## Install
```
> TODO
```
## Usage
```
> TODO
```
## Maintainers
Captain: [@Kubuxu](https://github.com/Kubuxu).
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/multiformats/c-multihash/issues).
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
[MIT](LICENSE) © Protocol Labs, Inc

View File

@ -1,3 +1,5 @@
#pragma once
#include "errors.h"
// definitions of hash functions
@ -31,7 +33,16 @@ static const int mh_all_hashes[] = {
#define MH_H_COUNT (int)(sizeof(mh_all_hashes) / sizeof(mh_all_hashes[0]))
/**
* Given the id, return the hash name
* @param hash the id (such as MH_H_SHA1)
* @returns the name as text, such as "sha1"
*/
const char *mh_hash_name(int hash);
// returns length in bytes or if returns is < 0 it is an error
/**
* Given the id, return the default length
* @param hash the id
* @returns the default length of that hash
*/
int mh_hash_default_length(int hash);

View File

@ -3,26 +3,69 @@
#include <stddef.h>
// returns hash code or error (which is < 0)
/**
* Functions for working with a multihash.
* A multihash is a hash with a prefix "code" that
* helps determine what type of hash this is.
* code name
* 0x00 identity
* 0x11 sha1
* 0x12 sha2-256
* 0x13 sha2-512
* 0x14 sha3-512
* 0x15 sha3-384
* 0x16 sha3-256
* 0x17 sha3-224
* 0x18 shake-128
* 0x19 shake-256
* 0x40 blake2b
* 0x41 blake2s
* # 0x0400-0x040f reserved for application specific functions
* # 0x14 formerly had the name "sha3", now deprecated
*/
/**
* returns hash code or error (which is < 0)
* @param mh the multihash
* @param len the length of the multihash
* @returns errors ( < 0 ) or the multihash
*/
int mh_multihash_hash(const unsigned char *multihash, size_t len);
// returns length of multihash or error (which is < 0)
/***
* returns the length of the multihash's data section
* @param mh the multihash
* @param len the length of the multihash
* @returns the length of the data section, or an error if < 0
*/
int mh_multihash_length(const unsigned char *multihash, size_t len);
// gives access to raw digset inside multihash buffer
// returns 0 or negative error
int mh_multihash_digset(const unsigned char *multihash, size_t len,
const unsigned char **digset, size_t *digset_len);
/**
* gives access to raw digest inside multihash buffer
* @param multihash the multihash
* @param len the length
* @param digest the results
* @returns error if less than zero, otherwise 0
*/
int mh_multihash_digest(const unsigned char *multihash, size_t len,
unsigned char **digest, size_t *digest_len);
// returns length in bytes of buffer needed to store multihash
// with given hashcode and with given digset length
// returns length or negative error code
int mh_new_length(int code, size_t digset_len);
/**
* determine the size of the multihash given the data size
* @param code currently not used
* @param hash_len the data size
* @returns hash_len + 2 (until the code parameter (varint) is added
*/
int mh_new_length(int code, size_t digest_len);
// writes multihash into a buffer, the buffer needs to be at least
// mh_new_length() bytes long.
// returns negative error code or 0
int mh_new(unsigned char *buffer, int code, const unsigned char *digset,
size_t digset_len);
/***
* create a multihash based on some data
* @param buffer where to put the multihash
* @param code the code
* @param digest the data within the multihash
* @returns error (if < 0) or 0
*/
int mh_new(unsigned char* buffer, int code, const unsigned char *digest,
size_t digest_len);
#endif /* end of include guard */

View File

@ -1,5 +1,10 @@
#include "mh/errors.h"
/**
* Convert an error code into a string
* @param code the error code
* @returns the error as text
*/
const char *mh_error_string(int code) {
switch (code) {
case MH_E_NO_ERROR:

View File

@ -1,3 +1,7 @@
/***
* Some helpers in identifying hashes
*/
#include <stdlib.h>
#include "mh/hashes.h"
@ -26,7 +30,11 @@ static const struct hash_info {
mh_assert_static(sizeof(hash_infos) / sizeof(hash_infos[0]) == MH_H_COUNT);
// Searches for given hash in hash info table
/**
* Given the id, return a struct that shows the id, name, and default length
* @param hash the id, such as MH_H_SHA1
* @returns a hash_info struct that has an int, const char* and int
*/
static const struct hash_info *find_hash(int hash) {
// naive search, could be replaced with binary
unsigned int i = 0;
@ -38,13 +46,22 @@ static const struct hash_info *find_hash(int hash) {
return NULL;
}
/**
* Given the id, return the hash name
* @param hash the id (such as MH_H_SHA1)
* @returns the name as text, such as "sha1"
*/
const char *mh_hash_name(int hash) {
const struct hash_info *info = find_hash(hash);
return info ? info->name : NULL;
return (info != NULL) ? info->name : NULL;
}
/**
* Given the id, return the default length
* @param hash the id
* @returns the default length of that hash
*/
int mh_hash_default_length(int hash) {
const struct hash_info *info = find_hash(hash);
return info ? info->length : MH_E_UNKNOWN_CODE;
return (info != NULL) ? info->length : MH_E_UNKNOWN_CODE;
}

View File

@ -1,6 +0,0 @@
#include <stdio.h>
int main(void) {
printf("Hello World\n");
return 0;
}

View File

@ -9,69 +9,100 @@
#define VARINT_MASK (1 << 7)
/**
* checks the length of a multihash for validity
* @param len the length of the multihash
* @returns errors or MH_E_NO_ERROR(0)
*/
static int check_len(size_t len) {
if (len < 1) {
if (len < 1)
return MH_E_TOO_SHORT;
} else if (len >= 128) {
else if (len >= 128)
return MH_E_TOO_LONG;
}
return MH_E_NO_ERROR;
}
/**
* do some general checks on the multihash for validity
* @param mh the multihash
* @param len the length of the multihash
* @returns errors or MH_E_NO_ERROR(0)
*/
static int check_multihash(const unsigned char mh[], size_t len) {
int error;
int err;
if (len < 3)
return MH_E_TOO_SHORT;
if (mh[0] & VARINT_MASK) {
// In near future multihash format will be
// extended with varints, this is how we are protecting
// against it.
// This value is a varint, but there are currently no supported
// values that require more than a single byte to represent.
return MH_E_VARINT_NOT_SUPPORTED;
} else if (mh[1] & VARINT_MASK) {
return MH_E_VARINT_NOT_SUPPORTED;
}
error = check_len(mh[1]);
if (error)
return error;
err = check_len(mh[1]);
return MH_E_NO_ERROR;
return err;
}
// returns hash code or error (which is < 0)
/**
* returns hash code or error (which is < 0)
* @param mh the multihash
* @param len the length of the multihash
* @returns errors ( < 0 ) or the multihash
*/
int mh_multihash_hash(const unsigned char *mh, size_t len) {
if (check_multihash(mh, len))
return check_multihash(mh, len);
int err = check_multihash(mh, len);
if (err)
return err;
return (int) mh[0];
}
// returns length of multihash or error (which is < 0)
/***
* returns the length of the multihash's data section
* @param mh the multihash
* @param len the length of the multihash
* @returns the length of the data section, or an error if < 0
*/
int mh_multihash_length(const unsigned char *mh, size_t len) {
if (check_multihash(mh, len))
return check_multihash(mh, len);
int err = check_multihash(mh, len);
if (err)
return err;
return (int) mh[1];
}
// gives access to raw digset inside multihash buffer
// returns 0 or negative error
int mh_multihash_digset(unsigned char *multihash, size_t len, unsigned char **digset,
size_t *digset_len) {
int error = check_multihash(multihash, len);
if (error)
return error;
/**
* gives access to raw digest inside multihash buffer
* @param multihash the multihash
* @param len the length
* @param digest the results
* @returns error if less than zero, otherwise 0
*/
int mh_multihash_digest(const unsigned char *multihash, size_t len, unsigned char **digest,
size_t *digest_len) {
int err = check_multihash(multihash, len);
if (err)
return err;
(*digset_len) = (size_t) mh_multihash_length(multihash, len);
(*digset) = multihash + 2; // Always true without varint
(*digest_len) = (size_t) mh_multihash_length(multihash, len);
(*digest) = (unsigned char*)multihash + 2; // Always true without varint
return MH_E_NO_ERROR;
return 0;
}
/**
* determine the size of the multihash given the data size
* @param code currently not used
* @param hash_len the data size
* @returns hash_len + 2 (until the code parameter (varint) is added
*/
int mh_new_length(int code, size_t hash_len) {
// right now there is no varint support
// so length required is 2 + hash_len
@ -79,17 +110,24 @@ int mh_new_length(int code, size_t hash_len) {
return 2 + hash_len;
}
int mh_new(unsigned char *buffer, int code, const unsigned char *digset,
size_t digset_len) {
/***
* create a multihash based on some data
* @param buffer where to put the multihash
* @param code the code
* @param digest the data within the multihash
* @returns error (if < 0) or 0
*/
int mh_new(unsigned char* buffer, int code, const unsigned char *digest,
size_t digest_len) {
if (code & VARINT_MASK)
return MH_E_VARINT_NOT_SUPPORTED;
if (digset_len > 127)
if (digest_len > 127)
return MH_E_DIGSET_TOO_LONG;
buffer[0] = (unsigned char) ((unsigned int) code) & 255;
buffer[1] = (unsigned char) digset_len;
memcpy(buffer + 2, digset, digset_len);
buffer[1] = (unsigned char) digest_len;
memcpy(buffer + 2, digest, digest_len);
return MH_E_NO_ERROR;
return 0;
}

View File

@ -11,14 +11,14 @@ char error_buf[256];
static char *test_multihash_new_crafts_right_multihash(void) {
int error;
unsigned char buf[256]; // much bigger than needed
size_t digset_len = -1;
const unsigned char *digset = NULL;
size_t digest_len = -1;
const unsigned char *digest = NULL;
error = mh_multihash_digset(sha1_example, sha1_example_length,
&digset, &digset_len);
mu_assert("getting digset", error == MH_E_NO_ERROR);
error = mh_multihash_digest(sha1_example, sha1_example_length,
&digest, &digest_len);
mu_assert("getting digest", error == MH_E_NO_ERROR);
error = mh_new(buf, MH_H_SHA1, digset, digset_len);
error = mh_new(buf, MH_H_SHA1, digest, digest_len);
mu_assert("creating multihash", error == MH_E_NO_ERROR);
mu_assert("crafted multihash is the same", memcmp(sha1_example, buf,
@ -30,18 +30,18 @@ static char *test_multihash_new_crafts_right_multihash(void) {
static char *test_multihash_new_is_reversible(void) {
int error = MH_E_NO_ERROR;
int code = MH_H_SHA3_512;
const unsigned char *digset = random_512;
const size_t digset_len = 512 / 8;
const unsigned char *digest = random_512;
const size_t digest_len = 512 / 8;
unsigned char mh[256];
const size_t mh_len = mh_new_length(code, digset_len);
const size_t mh_len = mh_new_length(code, digest_len);
error = mh_new(mh, MH_H_SHA3_512, digset, digset_len);
error = mh_new(mh, MH_H_SHA3_512, digest, digest_len);
mu_assert("creating multihash", error == MH_E_NO_ERROR);
mu_assert("reading code", mh_multihash_hash(mh, mh_len) == MH_H_SHA3_512);
mu_assert("reading length", mh_multihash_length(mh, mh_len) ==
(int) digset_len);
(int) digest_len);
return NULL;
}