Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
wasm-watermarker
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nagayama15
wasm-watermarker
Commits
5d78143f
Commit
5d78143f
authored
Jul 11, 2019
by
nagayama15
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement function ordering watermark extractor
parent
233da654
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
140 additions
and
1 deletion
+140
-1
FunctionOrderingWatermarker.cpp
src/kyut/watermarker/FunctionOrderingWatermarker.cpp
+58
-0
FunctionOrderingWatermarker.hpp
src/kyut/watermarker/FunctionOrderingWatermarker.hpp
+12
-1
test_FunctionOrderingWatermarker.cpp
test/kyut/watermarker/test_FunctionOrderingWatermarker.cpp
+70
-0
No files found.
src/kyut/watermarker/FunctionOrderingWatermarker.cpp
View file @
5d78143f
...
...
@@ -5,6 +5,7 @@
#include <cassert>
#include <iostream>
#include "../BitStreamWriter.hpp"
#include "../CircularBitStreamReader.hpp"
namespace
kyut
::
watermarker
{
...
...
@@ -77,4 +78,61 @@ namespace kyut::watermarker {
return
numBits
;
}
std
::
size_t
extractFunctionOrdering
(
wasm
::
Module
&
module
,
BitStreamWriter
&
stream
,
std
::
size_t
maxChunkSize
)
{
assert
(
2
<=
maxChunkSize
&&
maxChunkSize
<
21
&&
"because 21! > 2^64"
);
// Number of bits extracted in the module
std
::
size_t
numBits
=
0
;
// Split according to the function in the module has body or not
// [begin, start) has no body, and [start, end) has
const
auto
start
=
std
::
partition
(
std
::
begin
(
module
.
functions
),
std
::
end
(
module
.
functions
),
[](
const
auto
&
f
)
{
return
f
->
body
==
nullptr
;
});
const
size_t
count
=
std
::
distance
(
start
,
std
::
end
(
module
.
functions
));
for
(
size_t
i
=
0
;
i
<
count
;
i
+=
maxChunkSize
)
{
const
auto
chunkSize
=
(
std
::
min
)(
maxChunkSize
,
count
-
i
);
const
auto
chunkBegin
=
start
+
i
;
const
auto
chunkEnd
=
chunkBegin
+
chunkSize
;
// Number of bits embedded in the chunk
const
auto
numBitsEmbeddedInChunk
=
factorialBitLengthTable
[
chunkSize
];
// Extract watermarks from the chunk
std
::
vector
<
wasm
::
Function
*>
functions
;
functions
.
reserve
(
chunkSize
);
std
::
transform
(
chunkBegin
,
chunkEnd
,
std
::
back_inserter
(
functions
),
[](
const
auto
&
f
)
{
return
f
.
get
();
});
std
::
sort
(
std
::
begin
(
functions
),
std
::
end
(
functions
),
[](
const
auto
&
a
,
const
auto
&
b
)
{
return
a
->
name
<
b
->
name
;
});
std
::
int64_t
watermark
=
0
;
std
::
int64_t
base
=
1
;
for
(
auto
it
=
chunkBegin
;
it
!=
chunkEnd
;
++
it
)
{
// Get index of the function `*it`
const
auto
pos
=
std
::
find_if
(
std
::
begin
(
functions
),
std
::
end
(
functions
),
[
it
](
const
auto
&
f
)
{
return
f
==
it
->
get
();
});
assert
(
pos
!=
std
::
end
(
functions
));
const
std
::
size_t
index
=
std
::
distance
(
std
::
begin
(
functions
),
pos
);
watermark
+=
index
*
base
;
base
*=
functions
.
size
();
// Remove the function found in this step
functions
.
erase
(
pos
);
}
stream
.
write
(
watermark
,
numBitsEmbeddedInChunk
);
numBits
+=
numBitsEmbeddedInChunk
;
}
return
numBits
;
}
}
// namespace kyut::watermarker
src/kyut/watermarker/FunctionOrderingWatermarker.hpp
View file @
5d78143f
...
...
@@ -4,8 +4,9 @@
#include <wasm.h>
namespace
kyut
{
class
BitStreamWriter
;
class
CircularBitStreamReader
;
}
}
// namespace kyut
namespace
kyut
::
watermarker
{
/**
...
...
@@ -17,6 +18,16 @@ namespace kyut::watermarker {
* @return Number of watermark bits embedded in the module.
*/
std
::
size_t
embedFunctionOrdering
(
wasm
::
Module
&
module
,
CircularBitStreamReader
&
stream
,
std
::
size_t
maxChunkSize
);
/**
* @brief Extract watermarks by changing the order of functions.
*
* @param module
* @param stream Output stream to save the watermarks.
* @param maxChunkSize The maximum number of functions in the watermark chunk.
* @return Number of watermark bits extracted from the module.
*/
std
::
size_t
extractFunctionOrdering
(
wasm
::
Module
&
module
,
BitStreamWriter
&
stream
,
std
::
size_t
maxChunkSize
);
}
// namespace kyut::watermarker
#endif // INCLUDE_kyut_watermark_FunctionOrderingWatermarker_hpp
test/kyut/watermarker/test_FunctionOrderingWatermarker.cpp
View file @
5d78143f
...
...
@@ -4,6 +4,7 @@
#include <wasm-io.h>
#include <kyut/BitStreamWriter.hpp>
#include <kyut/CircularBitStreamReader.hpp>
BOOST_AUTO_TEST_SUITE
(
kyut
)
...
...
@@ -83,6 +84,75 @@ BOOST_AUTO_TEST_CASE(embed_function_ordering) {
}
}
BOOST_AUTO_TEST_CASE
(
extract_function_ordering
)
{
wasm
::
Module
module
;
wasm
::
ModuleReader
{}.
read
(
KYUT_TEST_SOURCE_DIR
"/example/test1.wast"
,
module
);
// Embed 0b00
{
CircularBitStreamReader
s
{{
0
b0000
'
0000
}};
const
auto
numBitsEmbedded
=
embedFunctionOrdering
(
module
,
s
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsEmbedded
,
std
::
size_t
{
2
});
BitStreamWriter
w
;
const
auto
numBitsExtracted
=
extractFunctionOrdering
(
module
,
w
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsExtracted
,
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
tell
(),
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
data
().
size
(),
std
::
size_t
{
1
});
BOOST_REQUIRE_EQUAL
(
w
.
data
()[
0
],
std
::
uint8_t
{
0
b0000
'
0000
});
}
// Embed 0b01
{
CircularBitStreamReader
s
{{
0
b0100
'
0000
}};
const
auto
numBitsEmbedded
=
embedFunctionOrdering
(
module
,
s
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsEmbedded
,
std
::
size_t
{
2
});
BitStreamWriter
w
;
const
auto
numBitsExtracted
=
extractFunctionOrdering
(
module
,
w
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsExtracted
,
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
tell
(),
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
data
().
size
(),
std
::
size_t
{
1
});
BOOST_REQUIRE_EQUAL
(
w
.
data
()[
0
],
std
::
uint8_t
{
0
b0100
'
0000
});
}
// Embed 0b10
{
CircularBitStreamReader
s
{{
0
b1000
'
0000
}};
const
auto
numBitsEmbedded
=
embedFunctionOrdering
(
module
,
s
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsEmbedded
,
std
::
size_t
{
2
});
BitStreamWriter
w
;
const
auto
numBitsExtracted
=
extractFunctionOrdering
(
module
,
w
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsExtracted
,
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
tell
(),
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
data
().
size
(),
std
::
size_t
{
1
});
BOOST_REQUIRE_EQUAL
(
w
.
data
()[
0
],
std
::
uint8_t
{
0
b1000
'
0000
});
}
// Embed 0b11
{
CircularBitStreamReader
s
{{
0
b1100
'
0000
}};
const
auto
numBitsEmbedded
=
embedFunctionOrdering
(
module
,
s
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsEmbedded
,
std
::
size_t
{
2
});
BitStreamWriter
w
;
const
auto
numBitsExtracted
=
extractFunctionOrdering
(
module
,
w
,
10
);
BOOST_REQUIRE_EQUAL
(
numBitsExtracted
,
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
tell
(),
std
::
size_t
{
2
});
BOOST_REQUIRE_EQUAL
(
w
.
data
().
size
(),
std
::
size_t
{
1
});
BOOST_REQUIRE_EQUAL
(
w
.
data
()[
0
],
std
::
uint8_t
{
0
b1100
'
0000
});
}
}
BOOST_AUTO_TEST_SUITE_END
()
BOOST_AUTO_TEST_SUITE_END
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment