Plugins
From WatermillWiki
Contents |
Watermarking plugins in Watermill
Starting from version 1.4, Watermill features a plugin engine so that third-party watermarking algorithms can easily be added.
Implementation
Methods to implement
A watermarking plugin consists of a superclass of Watermill.kernel.Pool class member of the package Watermill.plugins. Basically, 2 functions (actually 4 but the first two can be past and copied) have to be implemented:
- watermark(Document,int)
- detect(Document,Watermark,int)
The Document abstraction
For both these functions, interaction with the actual data is done through a document abstraction (Watermill.kernel.Document class). A Document is a simple data model consisting of a set of (identifier,value) pairs. These pairs are stored in a Watermill.kernel.Identifiers object (id object initialized in the constructor). Identifiers can be easily enumerated (mimicing an exhaustive listing of the values of the database) using a java.util.Enumeration object (see code below).
From a document, the value associated to an identifier can be obtained using the getValue(Identifier) method. Bits of the Watermill.kernel.Value object obtained can be extracted and modified using the method Value.extractBit(int) and Value.setBit(boolean,int).
A convenient way to print out results of the detection process is to store them in a Watermill.kernel.Params object which can be seen as a container for the the values MC and TC, MC being the number of matching detected watermarked bits whereas TC is the total number of watermarked positions.
Sample Implementation
The implementation of watermark and detect methods for a basic watermarking method Watermill.plugins.SamplePool is detailed below (the full code is also available from the CVS repository of the project):
/*
* Watermarking algorithm
*
* @param seed a (potentially secret) integer to seed
* pseudo random generators used by the algorithm
* @param d the target watermarked database. Initially
* contains a copy of the unwatermarked database.
* @return
*/
public Watermark watermark(Document d,int seed) {
// This procedure marks a two column (key+value)
// relation. The key column contains primary whereas the
// value column is the one which is within the scope of a
// local constraint.
// Tuples are enumerated and the least significant bit
// is set to zero in every value.
Watermark res = new Watermark();
// perform an operation on every identifier (ie primary key) of the database
for (Enumeration e=identifiers.elements();e.hasMoreElements();) {
Identifier id = (Identifier)e.nextElement();
// get the associated value
Value v = d.getValue(id);
// set 0-th bit of v to true
Value vd = v.setBit(true,0);
d.setValue(id,v); // commit the modification
// store the distortion induced by the marking algorithm
res.put(id,vd);
}
d.endWatermark(); // flush operation in the underlying storage engine
return res;
}
/*
* Detection algorithm
*
* @param d the suspect document
* @param w the introduced watermark to compare with
* not used for blind algorithms
* @param seed a (potentially secret) integer to seed
* pseudo random generators used by the algorithm
*/
public Params detect(Document d,Watermark w,int seed){
Msg.verbose("Applying detection for sample pool");
int totalcount = 0; // number of watermarked positions
int matchcount = 0; // number of positions where found bits
// match their watermarked value
// container to store detection results
Params res = new Params();
for (Enumeration e=identifiers.elements();e.hasMoreElements();) {
Identifier id = (Identifier)e.nextElement();
Value v = d.getValue(id);
boolean b = v.extractBit(0);
totalcount++;
if (b)
matchcount ++;
}
res.store("TC",totalcount);
res.store("MC",matchcount);
res.store("correlation",(double)matchcount/(double)totalcount);
Msg.verbose("detect MC="+matchcount+" TC="+totalcount);
return res;
}
Note about performance
Memory and speed efficient implementations can not be done using the plugin system. Plugins have been introduced as a way to quickly add watermarking algorithms. For optimized algorithms, diving into the actual source code of Watermill is compulsory. Think of plugins as a convenient to do rapid prototyping.
Using a plugin
Compile the plugin and launch rmill with the freshly compiled class in the classpath. Then, you can create a pool of watermarks using the create pool command. For instance, with the following commands, you can obtain a watermarked database juliedb from the original database dbtest using the algorithm implemented in the SamplePool class.
create client "julie" "Julie Nicesmile" "2342342332324";
create "SamplePool" pool "samplepool" on "finances" with
local 1 on ("trans","trans_id","amount");
get instance "juliedb" for "julie" from "samplepool";
If you use the command create "MyPool" pool ..., watermill will try to load the watermarking algorithm implemented in the Watermill.plugins.MyPool package.
