Are int32s signed or unsigned in OSC (or is it unspecified?) - osc

The OSC Specification, version 1.0 specifies the "int32" data type as "32-bit big-endian two's complement integer". This implies that it's signed (otherwise, why would you write "two's complement"...), but it doesn't come right out and say it.
This comes up most clearly in the encoding of blobs: should it be legal to have a blob of length #x90000000 ? This number can be encoded as an unsigned 32-bit integer, but not as a signed 32-bit integer. I grant you, that's an extremely big blob (more than 2 gigabytes).

The specification gives you no more details. I checked the code of the C++ osc implementation I use and it's defined as:
typedef signed long int32;
the blob is defined as:
struct Blob{
Blob() {}
explicit Blob( const void* data_, unsigned long size_ )
: data( data_ ), size( size_ ) {}
const void* data;
unsigned long size;
};
So yes, it's signed integer for the "atomic" int32 type.
The blob on the other hand has it's size stored as unsigned long. So probably it can be larger. You may have to try it first, because I have only the implementation of osc pack here.

Related

Is there a difference between Signed and Unsigned LEB128, when *encoding* the number?

I understand that LEB128 decoders need to know whether an encoded number is signed or unsigned, but the encoder seems to work identically either way (though Wikipedia uses distinct functions for encoding signed and unsigned numbers).
If positive numbers are encoded the same way in Signed and Unsigned LEB128 (only the range changes), and negative numbers only occur in Signed LEB128, it seems more sensible to create a single function that encodes any integer (using the two's compliment when the argument is negative).
I implemented a function that works the way I described, and it seems to work fine.
This is not an implementation detail (unless I've misunderstood something). Any function that can encode Signed LEB128 makes any function that encodes Unsigned LEB128 completely redundant, so there would never be a good reason to create both.
I used JavaScript, but the actual implementation is not important. Is there ever a reason to have a Signed LEB128 encoder and an Unsigned one?
const toLEB128 = function * (arg) {
/* This generator takes any BigInt, LEB128 encodes it, and
yields the result, one byte at a time (little-endian). */
const digits = arg.toString(2).length;
const length = digits + (7 - digits % 7);
const sevens = new RegExp(".{1,7}", "g");
const number = BigInt.asUintN(length, arg);
const padded = "000000" + number.toString(2);
const string = padded.slice(padded.length % 7);
const eights = string.match(sevens).map(function(string, index) {
/* This callback takes each string of seven digits and its
index (big-endian), prepends the correct continuation digit,
converts the 8-bit result to a BigInt, then returns it. */
return BigInt("0b" + Boolean(index) * 1 + string);
});
while (eights.length) yield eights.pop();
};

How can I make a good hash function without unsigned integers?

I'm looking for a simple hash function that doesn't rely on integer overflow, and doesn't rely on unsigned integers.
The problem is that I have to create the hash function in blueprint from Unreal Engine (only has signed 32 bit integer, with undefined overflow behavior) and in PHP5, with a version that uses 64 bit signed integers.
So when I use the 'common' simple hash functions, they don't give the same result on both platforms because they all rely on bit-overflowing behavior of unsigned integers.
The only thing that is really important is that is has good 'randomness'. Does anyone know something simple that would accomplish this?
It's meant for a very basic signing symstem for sending messages to a server. Doesn't need to be top security... it's for storing high scores of a simple game on a server. The idea is that I would generate several hash-integers from the message (using different 'start numbers') and append them to make a hash-signature ). I just need to make sure that if people sniff the network messages send to the server that they cannot easily send faked messages. They would need to provide the correct hash-signature with their message, which they shouldn't be able to do unless they know the hash function being used. Ofcourse if they reverse engineer the game they can still 'hack' it, but I wouldn't know how to counter that...
I have no access to existing hash functions in the unreal engine blueprint system.
The first thing I would try would be to simulate the behavior of unsigned integers using signed integers, by explicitly applying the modulo operator whenever the accumulated hash-value gets large enough that it might risk overflowing.
Example code in C (apologies for the poor hash function, but the same technique should be applicable to any hash function, at least in principle):
#include <stdio.h>
#include <string.h>
int hashFunction(const char * buf, int numBytes)
{
const int multiplier = 33;
const int maxAllowedValue = 2147483648-256; // assuming 32-bit ints here
const int maxPreMultValue = maxAllowedValue/multiplier;
int hash = 536870912; // arbitrary starting number
for (int i=0; i<numBytes; i++)
{
hash = hash % maxPreMultValue; // make sure hash cannot overflow in the next operation!
hash = (hash*multiplier)+buf[i];
}
return hash;
}
int main(int argc, char ** argv)
{
while(1)
{
printf("Enter a string to hash:\n");
char buf[1024]; fgets(buf, sizeof(buf), stdin);
printf("Hash code for that string is: %i\n", hashFunction(buf, strlen(buf)));
}
}

ICU: Which compare API to use?

I read the documentation on the different compare APIs that ICU provides, but couldn't quite get the difference between them.
int8_t icu::UnicodeString::compare (const UnicodeString &text ) const
int8_t icu::UnicodeString::caseCompare (
int32_t start,
int32_t length,
const UChar * srcChars,
int32_t srcStart,
int32_t srcLength,
uint32_t options
)
virtual EComparisonResult icu::Collator::compare(
const UnicodeString &source,
const UnicodeString &target
)
To be able to do case insensitive operations on UTF16 strings, which API fits the bill and why?
Thanks!
from the docs:
UnicodeString::compare — this is a bitwise (exact) compare. So, A ≠ a.
UnicodeString::caseCompare — this is probably what you want to use, but keep reading. A = a and ß = ss, etc. You can see this demo to play with the comparison.
Collator - this is for locale-sensitive collation which is a different tool. Yes, you can do case sensitive comparison with the right options. But it does more powerful comparisons also, such as black-bird = BlackBird.
Hope this helps.

conversion of string to int and int to string using static_cast

I am just not able to convert different datatypes in c++,I know that c++ is a strong type language so,I
used here static_cast but I am facing a problem the error messages are
invalid static_cast from type 'std::string {aka std::basic_string}' to type 'int'
invalid conversion from 'int' to 'const char*' [-fpermissive]
#include <vector>
#include <iostream>
using namespace std;
int main()
{
string time;
string t2;
cin >> time;
int hrs;
for(int i=0;i!=':';i++)
{
t2[i]=time[i];
}
hrs=static_cast<int>(t2);
hrs=hrs+12;
t2=static_cast<string>(hrs);
for(int i=0;i!=':';i++)
{
time[i]=t2[i];
}
cout<<time;
return 0;
}
Making a string from an int (and the converse) is not a cast.
A cast is taking an object of one type and using it, unmodified, as if it were another type.
A string is a pointer to a complex structure including at least an array of characters.
An int is a CPU level structure that directly represents a numeric value.
An int can be expressed as a string for display purposes, but the representation requires significant computation. On a given platform, all ints use exactly the same amount of memory (64 bits for example). However, the string representations can vary significantly, and for any given int value there are several common string representations.
Zero, as an int on a 64 bit platform, consists of 64 bits at low voltage. As a string, it can be represented with a single byte "0" (high voltage on bits 4 and 5, low voltage on all other bits), the text "zero", the text "0x0000000000000000", or any of several other conventions that exist for various reasons. Then you get into the question of which character encoding scheme is being used - EBCDIC, ASCII, UTF-8, Simplified Chinese, UCS-2, etc.
Determining the int from a string requires a parser, and producing a string from an int requires a formatter.

How to hash with ed25519-donna

I apologize for asking somewhat of a programming question, but I want to be sure I'm properly using this library cryptographically.
I have managed to implement ed25519-donna except for hashing the data for a signature.
As far as I can tell, this is the function that hashes data:
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
but I can't figure out what *hash is. I'm fairly certain that *in and inlen are the data to be hashed and its length.
Is it something specific to SHA512?
How can one hash with ed25519-donna?
Program hangs
I've compiled with ed25519-donna-master/ed25519.o and the OpenSSL flags -lssl -lcrypto. The key generation, signing, and verification functions work as expected.
It's running without error, but the application hangs on these lines, and the cores are not running at 100%, so I don't think it's busy processing:
extern "C"
{
#include "ed25519-donna-master/ed25519.h"
#include "ed25519-donna-master/ed25519-hash.h"
}
#include <openssl/rand.h>
unsigned char* hash;
const unsigned char* in = convertStringToUnsignedCharStar( myString );
std::cout << in << std::endl;
std::cout << "this is the last portion output and 'in' outputs correctly" << std::endl;
ed25519_hash(hash, in, sizeof(in) );
std::cout << hash << std::endl;
std::cout << "this is never output" << std::endl;
How can this code be modified so that ed25519_hash can function? It works the same way regardless of whether hash and in are unsigned char* or uint8_t*s.
For uint8_t*, I used this code:
uint8_t* hash;
const uint8_t* in = reinterpret_cast<const uint8_t*>(myString.c_str());
“…but I can't figure out what *hash is.”
That uint8_t *hash is the buffer (unsigned char*) that will contain the resulting hash after you called the function.
So, you're looking at a function that expects 3 parameters (also known as arguments):
an uint8_t * buffer to hold the resulting hash,
the input data to be hashed,
the length of the input data to be hashed.
“Is it something specific to SHA512?”
Nope, it's regular C source. But I think you’re a bit confused by the documentation. It states…
If you are not compiling against OpenSSL, you will need a hash function.
…
To use a custom hash function, use -DED25519_CUSTOMHASH
when compiling ed25519.c and put your custom hash implementation
in ed25519-hash-custom.h. The hash must have a 512bit digest and
implement
…
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
So, unless you are not compiling against OpenSSL and implementing your own hash function, you won't be needing this function. Looking at your code, you are compiling against OpenSSL, which means you're playing with the wrong function.
“How can one hash with ed25519-donna?”
By using the provided functionality the library offers.
Your question makes me wonder if you scrolled down to the “Usage” part of the readme, because it completely answers your question and tells you what functions to use.
For your convenience, let me point you to the part of the documentation you need to follow and where you find the functions you need to hash, sign, verify etc. using ed25519-donna:
To use the code, link against ed25519.o -mbits and:
#include "ed25519.h"
Add -lssl -lcrypto when using OpenSSL (Some systems don't
need -lcrypto? It might be trial and error).
To generate a private key, simply generate 32 bytes from a secure cryptographic source:
ed25519_secret_key sk;
randombytes(sk, sizeof(ed25519_secret_key));
To generate a public key:
ed25519_public_key pk;
ed25519_publickey(sk, pk);
To sign a message:
ed25519_signature sig;
ed25519_sign(message, message_len, sk, pk, signature);
To verify a signature:
int valid = ed25519_sign_open(message, message_len, pk, signature) == 0;
To batch verify signatures:
const unsigned char *mp[num] = {message1, message2..}
size_t ml[num] = {message_len1, message_len2..}
const unsigned char *pkp[num] = {pk1, pk2..}
const unsigned char *sigp[num] = {signature1, signature2..}
int valid[num]
/* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */
int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0;
…
As you see, it's all in there… just follow the documentation.